Reputation: 55
There is a lot of documentation and examples of firestore collections getting realtime updates. However, there is very little for those who wish to have a single document have real time updates. I want to have a single document (an item
), on a page where only the item
will be viewed and manipulated and any changes to document, will have realtime updating.
Here is my component that wants to do stuff with the item
:
import { Component, OnInit } from '@angular/core';
import { ItemsService } from '../shared/items.service';
import { ActivatedRoute, Router } from '@angular/router';
@Component({
selector: 'app-view-item',
templateUrl: './view-item.component.html',
styleUrls: ['./view-item.component.css']
})
export class ViewItem implements OnInit {
item;
private sub: any;
constructor(
// Service used for Firebase calls
private itemsService: ItemsService,
private route: ActivatedRoute,
private router: Router
) {}
ngOnInit() {
// Item retrieved from */item/:id url
this.sub = this.route.params.subscribe(params => {
this.getItem(params['id']);
});
}
getItem = (id) => {
this.itemsService.getItem(id).subscribe(res => {
console.log(res);
this.item = res;
console.log(this.item);
});
}
And the service it uses for calls:
import { Injectable } from '@angular/core';
import { AngularFirestore, AngularFirestoreDocument } from '@angular/fire/firestore';
@Injectable({
providedIn: 'root'
})
export class ItemsService {
constructor(
private firestore: AngularFirestore
)
getItem(id) {
return this.firestore.collection('items').doc(id).snapshotChanges();
}
}
The log I get for console.log(this.item)
is undefined
. Calling this.item
in the console returns the same. I am unsure of how to proceed and would appreciate any guidance. Logging res
in the console returns a byzantine object. Perhaps that's how I access the item
, but if so, why is it not saved in this.item
and how do I access the item
's values?
Upvotes: 0
Views: 460
Reputation: 1571
snapshotChanges
returns an observable of actions, not the actual value.
You should extract the value with action.payload.doc.data()
:
So your code should look like the following example.
getItem(id) {
return this.firestore.collection('items').doc(id).snapshotChanges()
.pipe(
map(actions => actions.map(a => {
const data = a.payload.doc.data();
const id = a.payload.doc.id;
return { id, ...data };
})
);
}
Or you can use valueChanges
of doc
.
getItem(id) {
return this.firestore.collection('items').doc(id).valueChanges();
}
Upvotes: 2