3
votes

Abonnement angulaire. Impossible d'accéder aux données

MISE À JOUR Voici comment j'ai réussi à le faire (faites défiler jusqu'à ma réponse ou voici le lien): https://stackoverflow.com/a/55013081/1729405

J'essaie de créer un APIService dans Angular 7. J'utilise subscribe pour pousser vers un tableau auquel je ne peux pas accéder via un autre service.

Voici la méthode du service api:

export class AdsHealthService {
  today = this.callResponseApiService.getAll();


  constructor(private callResponseApiService: CallResponseApiService) { }

  getHealthValue(interval, type) {
    let obj = this.today;
    console.log(obj);
  }
}

Voici comment j'essaie de l'appeler dans le service secondaire:

  getResponse(url):Observable<any> {
    return this.http.post(url, '', {responseType: 'text'});
  }

  getAll() {
      this.getResponse(this.todayApiUrl).subscribe(
        (response) => {
          this.data.push(response);
        });

      return this.data;
  }

Dans l'image ci-jointe se trouve ce que j'obtiens lorsque je console.log () la réponse. Cela ressemble à un tableau mais lorsque j'essaye d'accéder au premier élément, j'obtiens un message undefined . Qu'est-ce que je fais mal?? entrez la description de l'image ici


0 commentaires

4 Réponses :


3
votes

Cela se produit parce que le http.post est asynchrone, vous pouvez le rendre synchrone en rendant le getResponse () async , transformant le Observable à Promise par .toPromise () et en ajoutant wait avant le http.post puisque getResponse () ne renverra pas Observable mais des données brutes donc le .subscribe () n'est plus nécessaire.

  async getResponse(url) {
    return await this.http.post(url, '', {responseType: 'text'}).toPromise();
  }

  async getAll() {
    this.data = await this.getResponse('some url');
    return this.data
  }
  async some() {
    const data = await this.getAll();
    console.log(data);
    console.log(this.data);
  }


9 commentaires

Je reçois une promesse avec la solution que vous avez fournie. Comment tireriez-vous la valeur d'une promesse? async getAll () {let promise = this.http.post (this.todayApiUrl, '', {responseType: 'text'}). toPromise (); promise.then (function (valeur) {valeur de retour;}); this.today = attendre la promesse; console.log (this.today); // ceci renvoie une valeur de chaîne return this.today; } Dans la classe AdsHealthService: this.data = this.callResponseApiService.getAll (); console.log (this.data); // ceci renvoie un objet de promesse au lieu d'une chaîne Merci!


J'ai mis à jour la réponse. Je vous remercie de le faire remarquer. Parce que getAll () est async , vous devez également l'appeler avec wait.


Lorsque vous faites référence à this.data en dehors de la fonction async some (), je reste indéfini. Existe-t-il un moyen d'obtenir la valeur de la chaîne en dehors de la fonction asynchrone (car toutes les fonctions asynchrones renvoient une promesse)?


Que voulez-vous faire avec ces données simplement les afficher dans l'interface utilisateur ou une modification?


J'espère modifier les données renvoyées par la requête HTTP.


J'obtiens toujours le même résultat. Comme vous l'avez avec vous abonner.


J'ai pu l'obtenir en enchaînant les promesses. Je vous remercie beaucoup pour votre aide!


OK, pouvez-vous modifier ma réponse? Ou poster ici la solution?


Tu l'as eu! La réponse est ci-dessous. :)



0
votes

Vous n'obtenez pas de données ou de données nulles ou non définies, car votre point de terminaison de repos renverra des données dans le futur, mais votre déclaration de retour est renvoyée immédiatement.

Voici les moyens de résoudre ce problème

  • utiliser le tube async dans le modèle et .map dans le service
  • obtenez les données une fois prêtes dans votre composant en utilisant map

ci-dessous sont le code

export class AdsHealthService {

  constructor(private callResponseApiService: CallResponseApiService) {
     this.callResponseApiService.getAll().subscribe( (today) => {
       let obj = today;
       console.log(obj);
     });
  }

 rawdata = this.callResponseApiService.getAll();


}

Dans votre classe de composants

  // one method is fine to return data from rest endpoint
  getAll(url):Observable<any> {
     return this.http.post(url, '', {responseType: 'text'});
   }

Incase vous montrez directement les données dans le modèle, vous pouvez le faire en utilisant le tube async .

{{rawdata | async}}


1 commentaires

J'ai pu l'obtenir en utilisant Promises à la place. Pour une raison vraiment étrange, l'Observable ne reviendrait pas d'une manière que je pourrais obtenir les données. Je ne sais pas pourquoi. Merci pour votre avis!



1
votes

Dans votre service, vous auriez besoin des éléments suivants:

  if (!this.cacheService.has('some key')) {
    let data = this.yourServiceName.init();
    this.cacheService.set('some key', data)
  } else {
    let cache = this.cacheService.get('data');
    // do stuff here.
  }

Dans un autre service / composant, vous pouvez récupérer la promesse comme ci-dessous. Pour vous assurer que vous recevez une promesse, vous devez utiliser un bloc try catch.

let data = this.yourServiceName.getToday();
this.data.then((res) => {
// do stuff with 'res' here.
}

puis appelez:

  async getToday() {
    try {
      let today = await this.yourServiceName.getAll(this.todayApiUrl);
      return today;
    } catch(e) {
        console.log(e);
    }
  }


0 commentaires

0
votes

vous pouvez le faire comme ceci:

Dans votre composant d'application:

public getData(obj: appComponentModel){
    this.http.get(url).subscribe(res => obj.setData(res));
}

Dans votre service.ts:

public getDataFromService() {
  this._api.getData(this);
}


public setData(data: any){
 this.data=data;
}


1 commentaires

Tout d'abord, bienvenue dans Stack. Appréciez la réponse. Si jamais je reviens à une situation comme celle-ci, je vérifierai votre solution. :) Je n'y ai pas touché depuis son lancement.