Let's look at the read case. The following code will read the data from a property in our database:
let stream$ = this.angulatFireDatabase.object('/book').valueChanges();
As it is a stream, this means that we can get the data in one of two ways:
- Using the async pipe, which displays the observable as is, in the template
- Grabbing the data from the subscribe() method and assigning it to a property on your class
If we do the first scenario, it will look something like this:
@Component({
template: `
<div *ngIf="$book | async; let book;">
{{ ( book | async )?.title }}
</div>
`
})
export class Component {
book$: Observable<Book>;
constructor(private angularFireDatabase: AngularFireDatabase) {
this.book$ = this.angularFireDatabase
.object('/book')
.valueChanges()
.map(this.mapBook);
}
private mapBook(obj): Book {
return new Book(obj);
}
}
class Book {
constructor(title: string) { }
}
It is worth highlighting how we ask for the path in the database and transform the result with the .map() operator:
this.book = this.angularFireDatabase
.object('/book')
.map(this.mapBook);
In the template, we use the async pipe and an expression to show the title of our Book entity when it has been resolved:
<div *ngIf="book$ | async; let book">
{{ book.title }}
</div>
If we do the second scenario, it will look something like this in code:
@Component({
template: `
<div>
{{ book.title }}
</div>
`
})
export class BookComponent {
book:Book;
constructor(private angularFireDatabase: AngularFireDatabase) {
this.angularFireDatabase.object('/book')
.map(mapBook).subscribe( data => this.book = data );
}
mapBook(obj): Book {
return new Book(obj);
}
}
class Book {
constructor(title:string) {}
}
This will take away a little of the typing, but you now must remember to unsubscribe to your stream; this has not been added in the previous example. When possible, use the async pipe.