ElGecko_76 ElGecko_76 - 3 years ago 85
TypeScript Question

Show asynchronous datas of subscribe

I use a loop to retrieve the data stored in Firebase thanks to the subscribe function and forEach. When I do a console.log of my datas in the subscribe ("=== SUBSCRIBE ===") I have the good result, but when I do a console.log outside ("=== HOME ===" and "=== RETURN ==="), I have this result :

screen of console.log

I suppose it comes from the fact that it is asynchronous, how to fix this problem please ?

This is my code :

statut: FirebaseListObservable<any[]>;
statuts: Array<any> = [];

// Données à enregistrer dans FireBase
dateOfTheDay: string;
dayOfWeek: number;

constructor(public afDB: AngularFireDatabase, public storage: Storage) {
moment.locale('fr');
this.dateOfTheDay = moment().format('L'); // Date au format : 04/07/2017
this.dayOfWeek = moment().day(); // Numéro du jour de la semaine (Ex : 1 pour lundi)
this.statut = this.afDB.list('/statut');
}

statusToShow() {
this.statut.subscribe(statut => {
statut.forEach(s => {
if (this.dateOfTheDay === s.statut_date_tache) {
if (s.statut_id_tache in this.statuts === false) {
this.statuts[s.statut_id_tache] = s;
}
}
});

console.log('=== SUBSCRIBE ===');
console.log(this.statuts);
});

console.log('=== RETURN ===');
console.log(this.statuts);

return this.statuts;
}


Thanks in advance

Answer Source

Comment: This is borderline exact duplicate, but the latter part of question is not, therefore an answer.

You are correct with the assumption that this is asynchronous, and as presented here How do I return the response from an Observable/http/async call in angular2? you need to handle everything inside the callback (subscribe). BUT, here you want to return the response. You cannot do that, as said here: https://stackoverflow.com/a/39296015 it is not possible from subscribe.

What you can do, like presented in answer, you can use map and then return an observable, that you can subscribe to or use the async pipe if you want to use it in view.

Call the statusToShow() in the service from the component where you need it and subscribe to the value:

Service:

statusToShow() {
  return this.afDB.list('/statut').map(statut => {
    for(let s of statut) {
      if (this.dateOfTheDay === s.statut_date_tache) {
        if (s.statut_id_tache in this.statuts === false) {
          return localStatuts[s.statut_id_tache] = s;
        }
      }
    }
    // return something else if value is not found above
  });
}

Then you can subscribe to this observable in the component and you get the statut value:

Component:

constructor(private service: TodolistService) { }

ngOnInit() {
  this.service.statusToShow()
    .subscribe(statut => this.statut = statut)
}

I suggest you check the official http-tutorial. I know that you are using Firebase, but the idea is the same :)

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download