Async await not returning/showing any data from API

Issue

I have an Ionic 6 + Angular 14 app where for now I am trying to output data I get from an API…

I have created a service where I am getting the data from API and then I call the service in the component… The app compiles with no errors and there are no errors in the console in the browser…

Could someone help me figure out where I messed up?

Here is the code of my service:

async getCategories() {

 const token = await Preferences.get({ key: 'TOKEN_KEY' });

 const headers = new HttpHeaders().set('Authorization', `Bearer ${token.value}`);
 this.httpClient.get(`${environment.apiUrl}categories`, {headers}).subscribe(
 data => {
 this.categories = data;
    },
 error => {
 console.log('Error', error);
    }
  );
}

and here is the code from from the component.ts file:

ngOnInit() {
 this.getCategories();
}

getCategories() {
 this.categories = this.categoriesService.getCategories();
}

Solution

a lot of problems can occur when mixing Promise and Observable – I recommended use only Observables as long as you can, but in your case you replace it with.

 async getCategories() {
 const token = await Preferences.get({ key: 'TOKEN_KEY' });

 const headers = new HttpHeaders().set('Authorization', `Bearer 
 ${token.value}`);
 try { 
   const categories = await lastValueFrom(this.httpClient.get(`${environment.apiUrl}categories`, {headers}));
   return categories;
   catch(err) {
     // log error
 }
}
}

this method will return Promise with the data

the best way is to use the benefits of rxjs, by using only Observables

getCategories() {
    return from(Preferences.get({ key: 'TOKEN_KEY' })).pipe(
        switchMap(token => {
            const headers = new HttpHeaders().set('Authorization', `Bearer ${token.value}`);
            return this.httpClient.get(`${environment.apiUrl}categories`, {headers})
        })
    );
};

Inside your component you’ll have a variable storing the Observable like this:

 this.categories$ = this.yourService.getCategories();

and inside your template use async pipe for example:

 <div *ngFor="let category of categories$ | async">
   <p>{{ category }}</p>
 </div>

I recommended also reading about Interceptors in Angular
this is the perfect place to add the Authorization token.

good luck 🙂

Answered By – Eli Porush

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published