web-dev-qa-db-fra.com

S'abonner à observable renvoie undefined

J'essaie donc de m'abonner à un service simple qui renvoie des données à partir d'un fichier JSON local. 

J'ai réussi à faire fonctionner le service, je peux le déconnecter dans la fonction, mais lorsque je m'abonne au service dans le composant angulaire 2, il est toujours indéfini. Je ne sais pas pourquoi? Toute aide serait très appréciée.

Service API

export class ApiService {
   public data: any;

   constructor(private _http: Http) {
   }

   getData(): any {
       return this._http.get('api.json').map((response: Response) => { 
       console.log('in response', response.json()); //This logs the Object
       this.data = response.json();
       return this.data;
   })
   .catch(this.handleError);
   }
}

Composant

export class AppComponent {
   public data: any
   public informationData;

   constructor(private _api: ApiService) {}

   public ngOnInit(): void {
      console.log(this.getDataFromService()); // This return undefined
   }

   public getDataFromService() {
      this._api.getData().subscribe(response => {
          this.informationData = response;
          return this.informationData;
      });
   }
}
3
Sam Kelham

Peut-être que quelques images aident?

Les chiffres ici indiquent l'ordre des opérations.

Envoi de la requête HTTP  enter image description here

  1. Le composant est initialisé et appelle la méthode getMovies du movieService.
  2. La méthode movieService getMovies renvoie un observable. PAS les données à ce stade.
  3. Le composant appelle subscribe sur l'observable renvoyé.
  4. La demande get est soumise au serveur pour traitement.
  5. La méthode ngOnInit est terminée.

Aucun code ici après la subscribe ne peut accéder à la propriété movies car les données n'ont pas encore été renvoyées.

Recevez la réponse HTTP  enter image description here

Plus tard, à un moment donné ...

  1. Les films sont remis au service.
  2. Si le processus aboutit, la première fonction de rappel est exécutée.
  3. La propriété films locaux est attribuée aux films renvoyés par le service. Ce n'est qu'ici que la propriété movies est finalement définie. 

Si vous tentez d'accéder à la propriété de films avant l'étape 8, une erreur se produit.

Pouvons-nous accéder à la valeur ici? NON  enter image description here

Pour résoudre ce problème:  enter image description here

15
DeborahK

Vous avez un problème entre la synchronisation et la fonction async. Votre problème est le suivant: getDateFromService est synchrone et le contenu qu'il contient est asynchrone. Ainsi, lorsque la fonction ngOnInit appelle getDataFromService, votre code n'attend pas la tâche async. vous devez getDataFromService renvoyer un observateur ou implémenter le retour de votre API (vous devez choisir).

public ngOnInit(): void {
  console.log(this.getDataFromService().subscribe(data => console.log(data)); // This return undefined
}

public getDataFromService() {
  return this._api.getData();
}
0
Antoine Clavijo
objResponse;
this.service.getData().subscribe((result: any)=> { 
this.objResponse=result;
}

Retourner quelque chose ne sera pas nécessaire

0
mehul

Au lieu de vous connecter à la méthode ngOnInit () comme vous le faisiez

 public ngOnInit(): void {
      console.log(this.getDataFromService()); // This return undefined    }

se connecter à la méthode subscribe () en tant que

export class AppComponent {
  public data: any
  public informationData;

  constructor(private _api: ApiService) {}

  public ngOnInit(): void {
    this.getDataFromService(); //don't log here, logging here will return undefined
  }

  public getDataFromService() {
    this._api.getData().subscribe(response => {
      this.informationData = response;
      console.log(this.informationData); //log here, like this
      return this.informationData;
    });
  }
}
0
dips