0

I am flummoxed as to why my list will not display.

I am working with the Firebase Realtime Database, and I have no problem at all retrieving and displaying data filed under nodes with the simplest of structures. For example, retrieving data from -|cuisines -|itemId -key:value works just fine.

In cuisines.ts I can throw in a

items: Observable<any[]>;

with a

this.items = database.list('cuisines').valueChanges();

in the constructor, and this HTML

<ion-list>
<ion-item class="text" *ngFor="let item of items | async">
{{item.name}}
</ion-item>
</ion-list>

everything works just fine. My list of cuisines displays and I'm happy.

If, however, I try to use *ngFor to display data that I try to retrieve from the database at this location -|cuisines -$uid -|itemId -key:value, the data does not display.

So, in cuisines.ts, I have

  items: Observable<any[]>;

constructor(private database: AngularFireDatabase, private auth: AngularFireAuth) {
  this.auth.authState.subscribe(user => {
    if(user) this.userId = user.uid
  });
  this.items = database.list(`cuisines/${this.userId}`).valueChanges();

I have also tried

this.items = database.list('cuisines/' + this.userId).valueChanges();

All of this with the same HTML as above. I get no obvious errors. When I console.log(this.items), I get this:

Observable {_isScalar: false, source: Observable, operator: MapOperator}
operator
:
MapOperator {project: ƒ, thisArg: undefined}
source
:
Observable {_isScalar: false, source: Observable, operator: DistinctUntilChangedOperator}
_isScalar
:
false
__proto__
:
Object

All my rules are set as openly as possible at the moment, so that's not the problem. It's just that my list does not display. I isolated it down to the database path through a lot of trial and error. When I actually enter a userId into the code in the database path instead of this.userId my list also displays properly. Any help would be appreciated.

1 Answer 1

1

The problem is in this block:

constructor(private database: AngularFireDatabase, private auth: AngularFireAuth) {
  this.auth.authState.subscribe(user => {
    if(user) this.userId = user.uid
  });
  this.items = database.list(`cuisines/${this.userId}`).valueChanges();

Your this.auth.authState.subscribe registers a callback to capture this.userId; however, you immediately use this.userId on the next line, before your subscriber has been called (even if the value is already available, your callback won't get called until the next tick of the event loop).

You need to simply move this line:

this.items = database.list(`cuisines/${this.userId}`).valueChanges();

Inside the subscribe callback. This means your user will wait a moment to see data, so you might want a loader or an empty message.

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.