I have been building an App using the latest releases and Angular and AngularFire. When using the documentation provided, I can do all the CRUD operations just as prescribed in the Docs. However, I am having a difficult time understanding how to convert it to a service.
For example: Let's say I have a collection of crew members. There may be several components that need to consume the collection data containing all info about the crew members. It clearly makes sense to do this using a service and not do this massive chunk of code in each component.
DEMO CODE NOT MEANT TO BE MY ACTUAL CODE
// In Service Doc
crewCollectionRef: ....<Crew>;
crews: ...
constructor(private afs: AngularFirestore){
...
}
getCrews(){
return this.crews;
}
// In Component
ngOnInit(){
this.crews = this.service.getCrews();
}
I have been trying different ways to build a getCrews() method in a service file. But observable's don't seems to like being passed into some other component through a service. Is there any good blog post or even better perhaps a way to show how one might build services for Documents and Collections? I know this is something super easy but I am chasing my tail big time here.
I found this useful
https://coryrylan.com/blog/angular-observable-data-services
So I read this one. Thanks for taking the to share it. This is kind of confusing to me though. AngularFire is already mapping the data and ID to an Observable. I guess I was expecting this to be an Object that can be used.
routeCollection: AngularFirestoreCollection<Route>;
routes: Observable<Route[]>;
constructor(private afs: AngularFirestore) {
this.routeCollection = this.afs.collection<Route>('routes');
this.routes = this.routeCollection.snapshotChanges().map(actions => {
return actions.map(a => {
const data = a.payload.doc.data() as Route;
const id = a.payload.doc.id;
return { id, ...data };
});
});
}
getRoutes(){
return this.routes;
}
and I get this error:
Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.
when consuming like so:
routes = new Observable<Route[]>();
constructor(private service: RouteService) {
}
ngOnInit() {
this.routes = this.service.getRoutes();
}
look at https://github.com/angular/angularfire2/blob/master/docs/firestore/collections.md#example
Note the shirtId interface
export interface Shirt { name: string; price: number; }
export interface ShirtId extends Shirt { id: string; }
So your
routes: Observable<Route[]>;
should be
export interface RouteId extends Route { id: string; }
routes: Observable<RouteId[]>;
@tja4472 I have two files here that I would like to share:
RouteInterface
export interface Route {
id?: string,
value?: string,
display?: string
}
RouteService
import { Injectable } from '@angular/core';
import { AngularFirestore, AngularFirestoreCollection } from 'angularfire2/firestore';
import { Observable } from 'rxjs/Observable';
import { Subject, BehaviorSubject } from 'rxjs';
//import { Operator } from 'rxjs';
import 'rxjs/add/operator/map';
import { Route } from '../interfaces/route';
@Injectable()
export class RouteService {
routeCollection: AngularFirestoreCollection<Route>;
routes: Observable<Route[]>;
constructor(private afs: AngularFirestore) {
this.routeCollection = this.afs.collection<Route>('routes');
this.routes = this.routeCollection.snapshotChanges().map(actions => {
return actions.map(a => {
const data = a.payload.doc.data() as Route;
const id = a.payload.doc.id;
return { id, ...data };
});
});
}
getRoutes(){
return this.routes;
}
}
I tried the extends method you demonstrated above and I get an error stating the id is not a property of Route
Forget it all, and do as it says here.
https://angularfirebase.com/lessons/reactive-crud-app-with-angular-and-firebase-tutorial/
@callen5914 Did you ever figure this out? I'm running into the same scenario and can't seem to figure out how to set up AngularFire as a service.
For the sake of creating a more "complex" service, I went ahead and got the following working: https://gist.github.com/dylanjmcdonald/601e172f669e7c7cbab8942bd828cbee
However, it would be nice to clean that up a bit and be able to use a single AngularFirestoreCollection throughout the service methods. I ran into an issue creating a single AngularFirestoreCollection property on the service because I'm relying on an Observable on another service in order to set my collection path. The AngularFirestoreCollection was never defined when I'd try to use it because the method I would call would fire before the AngularFirestoreCollection would even be initialized on the services constructor due to having to subscribe to the "foreign" Observable - in this case it was the User Observable on my AuthService.