-2

I'm developing mobile application, using Ionic 4 & Angular 8. And I have some troubles, trying to achieve simple tasks.

So, I'm using: @ionic-native/native-storage & @angular/http in Angular service like this:

async getToken() {
    await this.storage.getItem('token')
        .then((res) => {
            this.token = res
        })
}

This is an Promise resolving function, am I right?

Then, I need to call this async/await function in another function:

latest() {
    this.getToken()

    let options = {
        headers: new HttpHeaders({
            'Auth-Key': this.token
        })
    }

    return this.http.get(this.env.API_URL + 'url', options)
}

Next step is call service function from the page:

getLatestVideo() {
    this.videoService.latest()
        .subscribe(data => {
            this.latestVideo = data;
        })
}

And now the problem:

The function getting 'token' from storage, did not finished, and Promise did not resolved, when I'm trying to get this token.

So, when I call HttpClient, and trying to get some data from api, I get an error, that says: 'token, you trying to call is null'.

Can someone explain how is Promises works? I can't get it

UPDATE 1:

Problem is resolved by 2 steps: Step 1: Make latest() async

async latest() {
    await this.getToken()

    let options = {
        headers: new HttpHeaders({
            'Auth-Key': this.token
        })
    }

    return this.http.get(this.env.API_URL + 'url', options)
}

Step 2: Make getLatestVideo() async too

async getLatestVideo() {
    const latestVideo = await this.videoService.latest();

    latestVideo.subscribe(data => {
        this.latestVideo = data;
    })
}

New problem: How to display data after all promises resolved inside view:

<div *ngFor="let video of latestVideo">{{ video.id }}</div>
Roman Khegay
  • 173
  • 2
  • 16

3 Answers3

1

Okay, you have to use some more awaits.

async latest() {
  await this.getToken()

  let options = {
      headers: new HttpHeaders({
          'Auth-Key': this.token
      })
  }
  return this.http.get(this.env.API_URL + 'url', options)
}

Next step

async getLatestVideo() {
  const latestVideo = await this.videoService.latest();
  latestVideo.subscribe(data => {
          this.latestVideo = data;
      })
}

Maybe this will help?

Alexander Elert
  • 152
  • 1
  • 5
  • 1
    No. If `latest()` doesn't await `this.getToken()`, then it'll make the second HTTP call immediately, before token is retrieved. – mbojko Feb 13 '20 at 07:57
  • I have added async await to latest(), I get token, I get info from server. But the problem is now, that I cant display it in .html with *ngFor – Roman Khegay Feb 13 '20 at 08:02
  • Ah, didn't know that get token is also async. But in the Angular question i can't help, sorry :) Could you just wrap a if araound the ngFor and wait, til the data is complete? – Alexander Elert Feb 13 '20 at 08:04
  • May this be helpful? https://stackoverflow.com/questions/34657821/ngif-and-ngfor-on-same-element-causing-error – Alexander Elert Feb 13 '20 at 08:19
0
getToken(): Observable<string> {
    return from(this.storage.getItem('token'));
}

latest() {
  return this.getToken().pipe(
    switchMap(token => {
        const headers = new HttpHeaders({ auth: token });
        return this.http.get(this.env.API_URL + 'video', { headers });
    }),
  )
}
Roman Khegay
  • 173
  • 2
  • 16
0

Instead of making all of your functions async-await, you can return promises. Eg getToken() { return this.storage.getItem('token') }

Then in latest you can simply have:

const token = await this.getToken()
let options = {
    headers: new HttpHeaders({
        'Auth-Key': token 
    })
}

return this.http.get(this.env.API_URL + 'url', options)
Jacob
  • 887
  • 1
  • 8
  • 17