samuelj123
samuelj123

Reputation: 67

How to get a function to wait for the data to load from a second function before executing in angular

I simply don't understand how async/await works; that's what I believe the problem is. I'm trying to load data from my service to my component, but I get an undefined. But the correct data loads properly from the function I'm calling. I imagine it's a way to re-structure the code so that async/await works, but I have no idea how.

Unfortunately, tutorials on async/await have just confused me more.

I've tried playing around with putting async/await in different places, but frankly I don't know what I'm doing.

This is the function in my component calling the other function from my UserService

async onSubmit() {
    console.log(await this.userservice.currentusercountry());
  }

This is the function in my userService

async currentusercountry() {
    let x;
    this.currentuser().subscribe(value => {
      console.log(value.country.toString());
      x = value.country.toString()
    });
    await console.log(x);
    return x;
  }

I expect to get something like this in my console.log

India         user.service.ts:65 
India         user.service.ts:68 
India         pg.component.ts:43 

But instead I get

undefined     user.service.ts:68 
undefined     pg.component.ts:43 
India         user.service.ts:65

Upvotes: 2

Views: 1214

Answers (5)

Eliseo
Eliseo

Reputation: 58039

Be the things "more natural". You has two Observables

  1. this.userservice.currentusercountry()
  2. this.currentuser()

you can use forkjoin to has an unique subscription

forkjoin([this.userservice.currentusercountry(),this.currentuser()])
         .subscribe(res=>{
            console.log(res[0]) //the response from currentuserCountry
            console.log(res[1]) //the response from currentuser
          })

Upvotes: 0

Eliran Eliassy
Eliran Eliassy

Reputation: 1600

Why don't you use RXJS switchMap?

e.g:

onSumit(){
  this.userService.currentUserContry().subscribe();
}

UserService

currentUserContry(){
  return this.currentUser().pipe(
    switchMap((res) => {
      const x = value.country.toString()
      return of(x);
    })
  )
}

Upvotes: 0

mbojko
mbojko

Reputation: 14699

I'll explain in comments why your function works how it works.

async currentusercountry() {
    let x;  // declare some variable, its value is initially undefined
    this.currentuser().subscribe(value => { // everything inside subscription will 
      console.log(value.country.toString()); // be executed LATER
      x = value.country.toString()
    });
    await console.log(x); // this is executed instantly
    return x; // this is also executed instantly, with current value of x, i. e. undefined
  }

Here's how to fix it:

async currentusercountry() {
    const value = await this.currentuser().toPromise();
    const x = value.country.toString();
    console.log(x);
    return x;
}

Upvotes: 0

Yash Rami
Yash Rami

Reputation: 2327

you can try like this

async onSubmit() {

    let data = await this.userservice.currentusercountry();
    console.log(data);
    console.log('works!!!!!');
}

userService

async currentusercountry() {
  return promise = new Promise ((resolve, reject) => {
    let x;
    this.currentuser().subscribe(value => {
      console.log(value.country.toString());
      x = value.country.toString()
      resolve(x); // here we are passing value to our component
    });
  });
}

Upvotes: 1

Doflamingo19
Doflamingo19

Reputation: 1639

try this:

async currentusercountry() {
    let x;
    this.currentuser().subscribe(value => {
      console.log(value.country.toString());
      x = value.country.toString();
  await console.log(x);
    return x;
    });

  }

Upvotes: 1

Related Questions