2017-07-26 5 views
1

Ich bin sicher, dass das Problem über Asynchronisierung ist, aber ich konnte die Lösung nicht finden. Ich habe einen Dienst erstellt, der ein Array von JSON-Daten erhält. In meiner Komponente möchte ich diese Daten anzeigen, wenn die Seite geladen ist. Ich erhalte keine Daten, wenn die Seite geladen wird, aber ich habe eine Schaltfläche erstellt und dieselbe Funktion für das onclick-Ereignis verwendet. Ich bekomme die Daten auf Klick Ereignis. Was mache ich falsch?Kann Ajax-Daten nicht auf Init in Angular erhalten 2

meine Komponente

import { Component } from '@angular/core'; 
import {PostService} from './post.service'; 

@Component({ 
    selector: 'app-root', 
    template: ` 

    {{test}} 
    <ul> 
    <li *ngFor="let item of jsonArray"> 
    {{item.title}} a 
    </li> 

    </ul> 
    <button on-click="onClick()">button</button> 
    ` 


}) 
export class AppComponent { 
    test; 
    jsonArray : any[]; 
    constructor(private _postService : PostService){ 


    } 

    onClick(){ 
    this.jsonArray = this._postService.getPosts(); 
    this.test = "clicked"; 
    } 

    ngOnInit(){ 
    this.jsonArray = this._postService.getPosts(); 
    this.test = "init"; 

    } 

} 

und meine Dienstklasse

import {Http} from '@angular/http' 
import 'rxjs/add/operator/map'; 
import {Injectable} from '@angular/core'; 


@Injectable() 
export class PostService { 

    private _url = "https://jsonplaceholder.typicode.com/posts"; 

    jsonArray: any[]; 
    getPosts():any[]{ 
     //return this._http.get(this._url).map(res =>res.json()); 
     this._http.get(this._url).subscribe(response => { 
      this.jsonArray = response.json(); 
      console.log(response.json()); 
      console.log("jsonArray",this.jsonArray); 
     }); 

     return this.jsonArray; 
    } 

    createPost(post){ 
     return this._http.post(this._url,JSON.stringify(post)).map(res =>res.json()); 
    } 
    constructor(private _http:Http){ 

    } 




} 
+0

https://stackoverflow.com/documentation/angular2/3577/angular-rxjs-subjects-and-observables -mit-api-requests/12348/basic-request # t = 20170726145040649751 – JGFMK

+0

Sie erhalten einen Fehler. Ich erstelle Ergebnis mit Ihrem Code. Erhalten Sie einen Fehler in der Konsole? –

+0

keine Fehler, ich versuche, die Daten auf der Seite nicht auf der Konsole zu sehen. Sehen Sie die Daten auf der Seite? @RajBahadurSingh – rematnarab

Antwort

2

Sie haben zwei Probleme in Ihren Diensten:

  1. Ihre return ist der Rückruf außerhalb, so dass die anfängliche leeres Array wird zurückgegeben
  2. Auch wenn es war nicht draußen, Sie können nicht Daten von subscribe zurückgeben.

Ich schlage vor, Sie oben auf Asynchronität lesen: How do I return the response from an asynchronous call?

Auch diese How do I return the response from an Observable/http/async call in angular2? erklären dieses Verhalten in kantigem Szenario.

Lesen Sie weiter auf die official tuto of http.

Das sagte, sagte sehr kurz - Sie müssen map in Service und subscribe in Komponente.

Zu Ihrer Frage:

Ich bekomme keine Daten, wenn die Seite geladen wird, aber ich erstellt einen Knopf und setze die gleiche Funktion auf seinem Onclick-Ereignisse. Ich bekomme die Daten auf Klick Ereignis.

Also lassen Sie uns in Ihrem Service-Methode tauchen und sehen, was los ist:

getPosts():any[]{ 
    this._http.get(this._url).subscribe(response => { 
     // hey, I'm doing this request now, but I don't know how long it will take 
     this.jsonArray = response.json(); 
     console.log(response.json()); 
     console.log("jsonArray",this.jsonArray); 
    }); 
    /* okay, so I fired the above request, I won't wait until it is complete, 
     I'll just execute the below while I am waiting!*/ 
    return this.jsonArray; 
} 

Also, wenn Sie die Anfrage Feuer auf OnInit führt sie die http-Anfrage, und während es ausgeführt wird Es gibt this.jsonArray zurück, bevor die HTTP-Anforderung beendet wurde.

Wenn Sie nun auf die Schaltfläche klicken, werden die http-Anforderungen erneut aktiviert, und bevor sie erneut abgeschlossen werden, werden Sie wieder mit this.jsonArray zurückgegeben. Aber hey, jetzt haben wir tatsächlich Werte von vorherige Anfrage, so dass Sie deshalb die Daten gut erhalten!

Wie bereits erwähnt, können Sie nicht wieder Daten von subscribe sowieso, auch wenn es im Inneren Rückruf wie so war:

getPosts():any[]{ 
    return this._http.get(this._url).subscribe(response => { 
     .... 
     return this.jsonArray; // WON'T WORK! 
    }); 
} 

Also, was Sie tun können, ist die Rückdaten von map, so tun:

Service:

getPosts():any[]{ 
    this._http.get(this._url) 
     .map(res => res.json()) 
    }); 
} 

Komponente:

ngOnInit(){ 
    this._postService.getPosts() 
    .subscribe(data => this.jsonArray = data) 
} 

ich wirklich empfehlen die ausgebrachten Links sorgfältig und mit dem Gedanken zu lesen :)

+0

vielen Dank, dies war sehr klärend – rematnarab

+0

Sie sind herzlich willkommen, froh, dass ich die Dinge ein wenig für Sie klären könnte! :) – Alex