1

as a follow-up to my previous question (on which I couldn't iterate over an array which seemed to be full), I now have an idea of what the problem is, and that should be that the list isn't full when I start to use it.

I then tried using a promise to wait for the task to be asynchronously executed and then proceed.

The thing is that for me the promise syntax is really off putting, it seems way too complicated for someone like me who has basically never used javascript outside of this one project.

I have this promise:

var promise=new Promise(function(resolve,reject){

    that.af.database.list('/users/'+that.authentificationService.getUserId()+'/favs'/*, { preserveSnapshot: true}*/)
      .subscribe(snapshots=>{
          snapshots.forEach(snapshot => {
            //console.log(snapshot.label);
            that.prefList.push(snapshot.label);                
            //this.prefList.push(snapshot.label);
          });
      });

      console.log("promise = done");
      return that.prefList;
  });

(that == this, by the way)

I get the "done" print, but I don't know if that's relevant

Then I try to do something within the then function of the promise:

promise.then(function(result){ (...) }

I have multiple console.logs inside there, but none are actually executed. What am I doing wrong?

promise.catch(function(e){
    console.log("catch entered");
    console.log(e);
  });

The catch doesn't ever log anything to the console either.

Joao Ventura
  • 65
  • 1
  • 11

2 Answers2

3

You don't have to create your own promise; you can use the RxJS toPromise operator (and you can use the map operator to map the array of favourites to an array of labels):

import 'rxjs/add/operator/first';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise';

...

return that.af.database
    .list('/users/' + that.authentificationService.getUserId() + '/favs')
    .map(favs => favs.map(fav => fav.label))
    .first()
    .toPromise();

You will also need to use the first operator, as the observable needs to complete before the promise resolves. AngularFire2 lists will continue to emit values as the database changes, but you only want the first value. (If you want changed values, a promise is not appropriate.)

cartant
  • 57,105
  • 17
  • 163
  • 197
2

You need to use the resolve function. Something like:

new Promise(function (resolve, reject) {
        that.af.database
            .list('/users/' + that.authentificationService.getUserId() + '/favs' /*, { preserveSnapshot: true}*/)
            .subscribe(snapshots => {
                snapshots.forEach(snapshot => {
                    //console.log(snapshot.label);
                    that.prefList.push(snapshot.label);
                    //this.prefList.push(snapshot.label);
                });
                resolve(that.prefList);
            });
    });
Mathew Berg
  • 28,625
  • 11
  • 69
  • 90