Reputation: 308
I have a Service call being made to get data from MongoDB. This part seems to be working and it logs correctly in the console.
This response is quite large and can take about 8Sec for the data to come in completely. For this purpose, i want to be able to update the data[]
in the component once the data has been retrieved.
My current solution is not working and I would like to know the correct and best practice for retrieving this in real time. Even if the response is taking a bit longer.
Service Call for getData
export class DataService {
dataArray: any[];
constructor(private http: Http){}
//get all data
getData(): any {
console.log('Api is calling getData...');
this.http.get('http://localhost:8080/api/data').map((res: Response) => res.json()).subscribe((res: any) => {
this.dataArray = res;
console.log('JSON: ' + this.dataArray);
return this.dataArray;
});
}
}
This is properly being imported into the MainComponent with no errors.
MainComponent
export class MainComponent implements OnInit{
data: Array<any>;
//Inject service here to use for getting data
constructor(private dataService: DataService){}
ngOnInit(){
//Set View Data with Request from Server
this.data = this.dataService.getData();
console.log("Data: " + this.data);
}
}
As you can guess my log here in MainComponent
does not display the appropriate data and actually displays undefined
. This happens to be an error that I can't seem to get past. I know there has to be a simple solution to it but for some reason, i can't locate a direct answer.
That's what I am hoping to get here, is an answer on how to update the MainComponent Array when the service has received the data from the request
Upvotes: 1
Views: 1017
Reputation: 73357
Just to throw the other option out there, if you do not want to subscribe.
Just as a sidenote, even if the following would work, and it would print the response, which it won't since this is asynchronous, and the console.log is executed before data has been fully received. But if it worked,
this.data = this.dataService.getData();
console.log("Data: " + this.data);
data
would be an Observable, which you'd still have to subscribe to. It can be done like kriss suggested, or you can just leave it like: this.data = this.dataService.getData();
and then use the async
pipe, which does the subscription for you. So if data were an array, you'd then do the following in your template:
<div *ngFor="let d of data | async">
{{d.myProperty}}
</div>
Just to throw this option out there :)
Upvotes: 5
Reputation: 1015
I think you should return Observable in your service and in your MainComponent subscribe to it (inside subscribe do initialization of data)
Example from angular documentation :
heroService :
getHeroes(): Observable<Hero[]> {
return this.http.get(this.heroesUrl)
.map(this.extractData)
.catch(this.handleError);
}
Some component
this.heroService.getHeroes()
.subscribe(
heroes => this.heroes = heroes,
error => this.errorMessage = <any>error);
Upvotes: 3