Reputation: 909
I have made many attempts to create an Angular 7 Service that will return an observable from Firestore but the latest version returns no data (the best result so far); I used Angularfire2 because it is supposed to be designed for observables and easier to use.
My Service is data4eatery.ts:
import { Injectable } from '@angular/core';
import { AngularFirestore, AngularFirestoreCollection } from 'angularfire2/firestore';
import { Observable } from 'rxjs';
import { IeTables } from './../components/models/eateries-model';
@Injectable({
providedIn: 'root'
})
export class Data4eateryService {
tablesCollection: AngularFirestoreCollection<IeTables>;
tables: Observable<IeTables[]>;
constructor(private afs: AngularFirestore) { }
getTables() {
this.tablesCollection = this.afs.
collection('eEatery').doc('J3XTNqSWGzmU4261BDHD'). //hard coded for testing
collection('eTable');
this.tables = this.tablesCollection.valueChanges();
return this.tables;
}
}
Code from the calling component:
tables: IeTables[] = [];
constructor( private data4eateryservice: Data4eateryService) { }
ngOnInit() {
const tablesObservable = this.data4eateryservice.getTables();
tablesObservable.subscribe((tablesData: IeTables[]) => {
this.tables = tablesData;
});
console.log('Tables', this.tables);
}
This returns Tables []
All the tutorials I found return observables from constants within the same component. I have been trying to sort this out on and off for weeks so please help me.
Upvotes: 0
Views: 1388
Reputation: 8558
The observable performs an async operation. So you need to assign values after subscribe
callback is called, like following:
tables: IeTables[] = [];
constructor( private data4eateryservice: Data4eateryService) { }
ngOnInit() {
const tablesObservable = this.data4eateryservice.getTables();
console.log('1 - OnInit Called');
tablesObservable.subscribe((tablesData: IeTables[]) => {
this.tables = tablesData;
console.log('2 - this.tables is set');
});
console.log('3 - After subscription');
}
The above code outputs to console as:
1 - OnInit Called
3 - After subscription
2 - this.tables is set
Therefore, this.tables
is not set until the subscription returns a value. So you need to move console.log
to inside of subscribe
callback like this:
ngOnInit() {
const tablesObservable = this.data4eateryservice.getTables();
tablesObservable.subscribe((tablesData: IeTables[]) => {
this.tables = tablesData;
console.log('this.tables: ',this.tables);
});
}
I think you need to get more familiar with the fundamentals of Observable
from RxJS
Official Angular Docs: https://angular.io/guide/observables
A tutorial: https://appdividend.com/2018/12/08/angular-7-observables-tutorial-with-example/
Another Tutorial: https://codecraft.tv/courses/angular/http/http-with-observables/
Upvotes: 3