Reputation: 1075
I have an angular app using firebase. The app has two services. The first one is for authentication. It has an observable with the current authenticated user.
import { AngularFireAuth } from 'angularfire2/auth';
import { Injectable } from '@angular/core';
import * as firebase from 'firebase';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class AuthService {
user$: Observable<firebase.User>;
constructor(private afAuth: AngularFireAuth) {
this.user$ = afAuth.authState;
}
getUser() {
console.log(this.user$);
}
loginWithEmailAndPassword(email, password) {
this.afAuth.auth.signInWithEmailAndPassword(email, password);
}
loginWithGoogle() {
this.afAuth.auth.signInWithRedirect(new firebase.auth.GoogleAuthProvider());
}
logOut() {
this.afAuth.auth.signOut();
}
}
The second services contains myFokos observable that subscribes to my firebsae realtime database list.
import { Observable } from 'rxjs/Observable';
import { AuthService } from './auth.service';
import { Injectable } from '@angular/core';
import { AngularFireDatabase } from 'angularfire2/database';
@Injectable()
export class MyListService {
myFokos: Observable<any[]>;
constructor(auth: AuthService, database: AngularFireDatabase) {
auth.user$.subscribe(user => {
console.log('User is logged in. UID: ' + user.uid);
this.myFokos = database.list('users/' + user.uid + '/glossaries').snapshotChanges();
});
}
}
Then I try to access myFokos observable from MyListService.
import { AuthService } from './../../services/auth.service';
import { MyListService } from './../../services/my-list.service';
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-my-fokos',
templateUrl: './my-fokos.component.html',
styleUrls: ['./my-fokos.component.css']
})
export class MyFokosComponent implements OnInit {
constructor(public myListService: MyListService, public auth: AuthServ
ice) { }
ngOnInit() {
this.myListService.myFokos.subscribe(x => {
console.log(x);
});
}
}
When I do this, I get an error in the console:
MyFokosComponent_Host.ngfactory.js? [sm]:1 ERROR TypeError: Cannot read property 'subscribe' of undefined
at MyFokosComponent.ngOnInit (my-fokos.component.ts:15)
at checkAndUpdateDirectiveInline (core.js:12364)
at checkAndUpdateNodeInline (core.js:13888)
at checkAndUpdateNode (core.js:13831)
at debugCheckAndUpdateNode (core.js:14724)
at debugCheckDirectivesFn (core.js:14665)
at Object.eval [as updateDirectives] (MyFokosComponent_Host.ngfactory.js? [sm]:1)
at Object.debugUpdateDirectives [as updateDirectives] (core.js:14650)
at checkAndUpdateView (core.js:13797)
at callViewAction (core.js:14148)
I think the problem is that myFokos observable is undefined until MyListService gets the user$ observable from AuthService, but I do not how I can fix it. I have tried to combine user$ and myFokos and then subscribe to that in the component, but that did not work.
I do not get the error when I navigate to another route and back. I can also get the data from HTML like this:
*ngFor="let foko of myListService.myFokos | async"
This question is not a duplicate of this question because the answer was to get the data from the database in the component instead. I do not want to this in my app because I am using the data from myFokos observable in multiple components.
Upvotes: 2
Views: 2880
Reputation: 549
Your code is not realy pure async code:
constructor(auth: AuthService, database: AngularFireDatabase) {
auth.user$.subscribe(user => {
console.log('User is logged in. UID: ' + user.uid);
this.myFokos = database.list('users/' + user.uid + '/glossaries').snapshotChanges();
});
}
This is much easier
constructor(auth: AuthService, database: AngularFireDatabase) {
this.myFokos$=auth.user$.switchMap(user => {
console.log('User is logged in. UID: ' + user.uid);
return database.list('users/' + user.uid + '/glossaries').snapshotChanges();
});
}
Upvotes: 1