2

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.

4
  • So the subscribe works okay in MyListService but the subscribe throws an error in MyFokosComponent? What happens when you put the suscribe in MyFokosComponent in the constructor, like MyListService, just out of curiosity? Commented Feb 20, 2018 at 13:53
  • @camden_kid, Yes, I can subscribe to the user$ observable in MyListService. However, the subscribe of the myFokos observable in MyFokosComponent throws an error. Commented Feb 20, 2018 at 17:17
  • I don't see where you are subscribing to myFokos observable in MyFokosComponent. I only see subscribe to auth.user$. Commented Feb 20, 2018 at 18:05
  • @camden_kid Sorry for late answer. I have updated the code now to your suggestions, but it is still not working... Commented Feb 27, 2018 at 10:32

1 Answer 1

1

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();
  });
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.