Problems async method

Hey all!

I hope you can help me, because I have some problems with the sequence of my functions (Firebase)
Note that I am a newbie (started development 3 weeks ago) and sorry for my bad english … :wink:

As you can see on the code below, I try to use async function with .then method. My function calls DB on Firebase, so some functions take longer to complete tasks.
I don’t understand why my function: SearchOrg() is finished after my function : Invitation() … while I specify to continue the code in .then …
I passed long time to try other methods as : await or Promise with function(resolve, reject) … but nothing succeeded.

async SearchOrg () {
        this.afDB.list('Attente/' + this.userID + '/Amis').snapshotChanges(['child_added', 'child_removed']).subscribe(actions => {
                   this.testUser = [];
                   console.log(this.userID);
                   actions.forEach(action => {
                   this.testUser.push(action.key); // payload.exportVal().Organisateur);
               });
               console.log(this.testUser);    // Displayed Last
            });
            return this.testUser;
 }


  async Invitation() {

  const test = await this.SearchOrg().then(() => {
      console.log(test);                                   // Displayed First
        if (test !== ' ') {
           this.MasterFlag = true;
           this.presentLoadingWithOptions();
        } else {
            this.Inviter = [];
            this.MasterFlag = false;
            this.afDB.list('Attente/' + this.userID + '/Organisateur').snapshotChanges(['child_added', 'child_removed'])
            .subscribe(actions => {
              actions.forEach(action => {
               this.Inviter.push(action.payload.exportVal().Organisateur);
              });
          });
      console.log(this.Inviter);                                // Displayed second
   }
  });
}

Many thanks for helps
BR
Yoann

Here’s what I would recommend:

  • forget that async and await exist for now;
  • read this post outlining three types of asynchronous functions, and decide which each of yours is;
  • pick a naming convention and follow it - here’s Google’s, for example;
  • declare proper types (no any) for every variable, parameter, and function return type;
  • never nest then or subscribe - if you feel the need to, break the task into a separate smaller function.

This will be frustrating, but following these rules will help your build tools guide you towards how to structure code clearly and avoid lots of common bugs. It will get more intuitive, eventually.

1 Like

Thanks to reply.

Ok, I just read about the use of Promise and function return (at first line). But if i don’t use async/await or nest .then , how i may be able to manage my tasks one after another.

thanks and good evening :slight_smile:

By chaining.

sign(food: string): Promise<string> {
  return ...;
}

seel(signed: string): Promise<string> {
  return ...;
}

deliver(seeled: string): void {
  ...;
}

signSeelAndDeliver(food: string): void  {
  sign(food)
    .then(signed => seel(signed))
    .then(seeled => deliver(seeled));
}

I tried this :

SearchOrg (): Promise<{test: any[]}> {
        return new Promise(function(resolve) {

          this.afDB.list('Attente/' + this.userID + '/Amis')
        .snapshotChanges(['child_added', 'child_removed']).subscribe(actions => {
                   actions.forEach(action => {
                   this.test.push(action.key);
               });
            });
            resolve(this.test);
 });
}


this.SearchOrg()
                  .then(test => this.Invitation(test));

But it doesn’t work… I get stuck in the SearchOrg function

Maybe i have to prefer Observable associated to .subscribe ??

One more rule: no “new Promise” in your code. There’s virtually never any need for it in app code, and it interferes with allowing types to shine through properly (and silently eats errors the way you’re using it, which is bad).

I discussed before how it’s important to avoid the crutch of any, especially when you’re starting out, because it inhibits your toolchain’s ability to help you diagnose problems. So declare an interface for all business-level objects. My minimal French is going to say searchOrg wants to return a list of Friends:

export interface Friend {
  name: string;
  ...
}

searchOrg(uid: string): Observable<Friend[]> {
  return this.afDB.list(`Attente/${this.userID}/Amis`)
    .snapshotChanges(["child_added", "child_removed"]).pipe(
      map(actions => actions.map(action => action.key)));
}

this.searchOrg().subscribe(friends => this.invite(friends));

Thank you ! Works well.

So if i understand correctly, Observable is more suitable for a database subscription ?

Encore désolé pour mon anglais :slight_smile:
Bonne semaine.

Two factors I would consider:

A. What is the original source providing? There are methods to convert Promises to Observables and vice-versa, but I generally attempt to avoid them, preferring to work with whatever I am given, thinking that that approach shines focus on what the app code is doing, as opposed to how it is doing it.

B. Is this a relationship or a one-night stand? Promises are specifically designed for a single operation, like “let me know when the Ionic-Native subsystem is ready for interaction”. Observables can do that as well, but really shine when the subscription is longer-lived, potentially providing a series of emissions.