web-dev-qa-db-fra.com

angular 5: Comment puis-je attendre la fin de mon service, puis passer à la tâche suivante?

J'ai un composant dans mon application angular5 appelé: product-list.component.ts. Dans ce composant, j'ai un constructeur, qui appelle une API REST.

product.service.ts

getAllProductsFromACategory(categoryName: string): any {
this.http.get('http://localhost:8080/VespaWebshopAPI
/api/Article/Category?categoryName=' + categoryName).
subscribe(data => {
var article: Article = {
    id: data[0].id,
    name: data[0].name,
    articleNr: data[0].articleNr,
    stock: data[0].stock,
    price: data[0].price,
    description: data[0].description
  };

  return article;
}); 

product-list.component.ts

public article: Article;

constructor(private route: ActivatedRoute, 
private productService: productService) { 
 //Call rest api
 this.article = 
 this.productService.getAllProductsFromACategory('Bremsen');
}

article.ts

export interface Article {
id : number;
name : string;
articleNr : string;
stock : number;
price : number;
description : string;
}

Dans mon html, je souhaite afficher certaines propriétés d'un article. Donc, si j'essaie d'exécuter ce code dans mon fichier product-list.component.html, j'obtiens l'erreur suivante:

{{ article.id }}

Erreur

ProductListComponent.html: 1 ERREUR TypeError: Impossible de lire la propriété 'id' d'undefined
sur Object.eval [comme updateRenderer] (ProductListComponent.html: 1)
sur Object.debugUpdateRenderer [comme updateRenderer] (core.js: 14727)
sur checkAndUpdateView (core.js: 13841)
sur callViewAction (core.js: 14187)
sur execComponentViewsAction (core.js: 14119)
sur checkAndUpdateView (core.js: 13842)
sur callViewAction (core.js: 14187)
sur execEmbeddedViewsAction (core.js: 14145)
sur checkAndUpdateView (core.js: 13837)
sur callViewAction (core.js: 14187)

L'API REST fonctionne; je l'ai testée. Je suppose qu'il y a juste le problème que les données doivent être chargées en premier, avant que la page html ne s'affiche. Quelque part ailleurs, je l'ai lu dans un ngFor, je devrais utiliser le canal | async, mais cela n'a pas fonctionné pour moi.

Alors, comment puis-je résoudre ce problème?

7
Ird

@TNII, @Hoang Duc, essayez de dire que c'est généralement un service qui expose Observables. Il se trouve dans un ngOnInit de votre composant lorsque vous vous abonnez à l'Observable.

//Simple return a get
getAllProductsFromACategory(categoryName: string): any {
   return this.http.get('http://localhost:8080/VespaWebshopAPI
   /api/Article/Category?categoryName=' + categoryName)
}

Dans le composant, généralement dans un ngOnInit lorsque nous nous abonnons à

ngOnInit()
{
    productService.getAllProductsFromACategory('Bremsen').
      subscribe(data => {
         if (data[0])
             this.article=data[0];
      })
}

le {{article? .id}} écrit en html est une façon abrégée de dire: si this.article est défini, montrez-moi this.article.id.

vérifiez si dans un navigateur écrivez http: // localhost: 8080/VespaWebshopAPI /api/Article/Category? categoryName = 'Bremsen', donnez-vous un tableau d'articles. Vérifiez si les éléments des tableaux ont des propriétés id, nom, etc. (ou renvoyez un élément avec d'autres propriétés)

6
Eliseo

Dans productService.getAllProductsFromACategory() remplacez subscribe par map pour que la méthode renvoie Observable<Article>

Dans constructor sur product-list.component.ts, abonnez-vous au Observable<Article> renvoyé de productService et définissez la valeur de this.article en cela

this.productService.getAllProductsFromACategory('Bremsen')
    .subscribe((art: Article) => {
        this.article = art;
    },
    (err: any) => console.error(err));

Dans votre html, mettez un *ngIf="article" dans l'élément environnant de votre interpolation {{ article.id }} pour l'empêcher de traiter jusqu'à ce que article obtienne une valeur valide.

4
Hoang Duc Nguyen