Skip to content

Instantly share code, notes, and snippets.

@katowulf
Created November 8, 2016 16:34
Show Gist options
  • Save katowulf/c493e19a932cd608b811907547be7a78 to your computer and use it in GitHub Desktop.
Save katowulf/c493e19a932cd608b811907547be7a78 to your computer and use it in GitHub Desktop.
AngularFire2 master detail example, uses routing with resolve method, Angular 2 + Firebase
import { Component } from '@angular/core';
import { AngularFire, FirebaseObjectObservable } from 'angularfire2';
import {ActivatedRoute, Params} from "@angular/router";
import {Observer} from "rxjs";
@Component({
selector: 'app-detail',
template: `
<h2>{{book.title}}</h2>
<p>{{book.author}}</p>
<a routerLink="/list" routerLinkActive="active">Back to List</a>
<button (click)="clicked()">click me</button>
`
})
export class DetailComponent {
book: FirebaseObjectObservable<any>;
constructor(route: ActivatedRoute, af: AngularFire) {
route.params.forEach(params => {
this.book = af.database.object(params['id']);
});
}
ngOnInit() {
// can't move the declaration of this.book to here or it never appears
}
}
import { Component } from '@angular/core';
import { AngularFire, FirebaseListObservable } from 'angularfire2';
import {ActivatedRoute} from "@angular/router";
@Component({
template: `
<ul>
<li class="text" *ngFor="let book of books | async">
<a [routerLink]="'/detail/' + book.$key">{{ book.title }}</a>
</li>
</ul>
`
})
export class ListComponent {
books: FirebaseListObservable<any[]>;
constructor(private af: AngularFire, private route: ActivatedRoute) {
// cannot be done in ngOnInit() or books never appear :(
this.route.data.forEach((data: {books: FirebaseListObservable<any>}) => this.books = data.books);
}
}
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { AngularFireModule } from 'angularfire2';
import { ListComponent } from './app.list';
import {DetailComponent} from "./app.detail";
import {RouterComponent} from "./app.router";
import {RootComponent} from "./app.root";
import {ListResolver} from "./resolve.list";
// Must export the config
export const firebaseConfig = {
apiKey: "AIzaSyBmfoEt1C19ltTFYDGYnkB4vlG0HlJ5VhU",
authDomain: "kato-books.firebaseapp.com",
databaseURL: "https://kato-books.firebaseio.com",
storageBucket: "kato-books.appspot.com",
messagingSenderId: "1068153257807"
};
@NgModule({
declarations: [
RootComponent,
ListComponent,
DetailComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
AngularFireModule.initializeApp(firebaseConfig),
RouterComponent
],
providers: [ListResolver],
bootstrap: [RootComponent]
})
export class AppModule { }
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
template: `
<!-- Routed views go here -->
<router-outlet></router-outlet>
`
})
export class RootComponent {}
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import {ListComponent} from "./app.list";
import {DetailComponent} from "./app.detail";
import {ListResolver} from "./resolve.list";
@NgModule({
imports: [
RouterModule.forRoot([
{ path: '', redirectTo: '/list', pathMatch: 'full' },
{
path: 'list',
component: ListComponent,
resolve: {
books: ListResolver
}
},
{ path: 'detail/:id', component: DetailComponent }
])
],
exports: [
RouterModule
]
})
export class RouterComponent {}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Ngapp</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root>Loading...</app-root>
</body>
</html>
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/
import { Injectable } from '@angular/core';
import {Resolve, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router';
import {AngularFire, FirebaseListObservable} from 'angularfire2';
import 'rxjs/add/operator/first';
@Injectable()
export class ListResolver implements Resolve<FirebaseListObservable<any>> {
constructor(private af: AngularFire) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<FirebaseListObservable<any>> {
let list = this.af.database.list('');
return new Promise((resolve, reject) => {
// must import 'rxjs/add/operator/first'; before using it here
list.first().subscribe(() => {
resolve(list)
}, reject);
});
}
//This also works, with a sad face
// return new Promise((resolve, reject) => {
// var sub = list.subscribe(() => {
// resolve(list);
// sub.unsubscribe();
// }, reject);
// });
// this does not work at all (never resolves)
// return list.toPromise();
}
@RyannGalea
Copy link

I was able to move the code into ngOnInit and it works fine here

 ngOnInit() {

this.route.data.forEach((data: {userAccount: FirebaseListObservable<any>}) => this.userResolve = data.userAccount);
this.userResolve.subscribe(
	res => {
		this.userAccount = res;
		console.log(this.userAccount)
	})

 }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment