1

In my Angular2 component constructor I store a value from Firebase into a variable.

this.dbAction.getDB().take(1).subscribe(data => {
  this.userVisitOrder = data[0][this.currentUserID]['settings']['visitOrder']; 
  console.log(this.userVisitOrder); // Value exists
});

I need exactly that variable to build my Observable to use specific firebase data. Also in my constructor:

this.visitsRef = afDatabase.list('data/users/' + this.currentUserID + '/visits/', ref => ref.orderByChild(this.userVisitOrder)); // Here the value is undefined

I think that´s an async issue, but how can I access the data stored in my variable?

The getDb()function in my dbAction Service looks like that:

getDB() {
  return this.afDatabase.list(`data`).valueChanges().map((data) => data);
}

And if I try to put the second code into the first like that:

this.dbAction.getDB().take(1).subscribe(data => {
  this.userVisitOrder = data[0][this.currentUserID]['settings']['visitOrder'];

  this.visitsRef = afDatabase.list('data/users/' + this.currentUserID + '/visits/', ref => ref.orderByChild(this.userVisitOrder));
  this.visits = this.visitsRef.snapshotChanges().map(changes => {
    return changes.map(c => ({ key: c.payload.key, ...c.payload.val() }));
  });
});

... I get the following console error:

enter image description here

2
  • The first situation definitely seems to be async. You can't access the return from .subscribe outside the block. The second issue seems like .getDB() isn't defined for some reason. Hard to tell for sure from this snippet how that would be. (i.e. you are not ever getting to execute the .subscribe.) Commented Nov 30, 2017 at 14:42
  • I edited my post with the getDb() helper function from my service. :) Commented Nov 30, 2017 at 15:09

1 Answer 1

1

You can chain the observables together with switchMap so one runs after the other.

this.dbAction.getDB().take(1)
    .switchMap(data => {
        this.userVisitOrder = data[0][this.currentUserID]['settings']['visitOrder'];

        this.visitsRef = afDatabase.list('data/users/' + this.currentUserID + '/visits/', ref => ref.orderByChild(this.userVisitOrder));

        return this.visitsRef.snapshotChanges();
    })
    .map(changes => {
        return changes.map(c => ({ key: c.payload.key, ...c.payload.val() }));
    });
    .subscribe(res => {// do something with result})
Sign up to request clarification or add additional context in comments.

5 Comments

Where do I declare this.visits for the Observable I call in my view?
@eleinad ah are you using it with an async pipe in your html?
@eleinad ah ok I misunderstood the question. What you have should work, the async pipe wont subscribe to this.visits until it is defined in this.dbAction.getDB().take(1).subscribe. The error you are getting says this.dbAction.getDB() is undefined, but I am unsure how its undefined
@eleinad try moving your code into ngOnInit instead of the constructor
I found the issue! I had this.visits.subscribe( () => this.spinner = false ); in my ngOnInit, because of async this.visits was still undefined. Moving this line into the this.dbAction.getDB().subscribe make it works! Many thanks for your help! :)

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.