1

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

n00dl3
  • 21,213
  • 7
  • 66
  • 76
Keeano
  • 309
  • 8
  • 33
  • Possible duplicate of [Waiting for an answer from server on http request in Angular 2](https://stackoverflow.com/questions/38316300/waiting-for-an-answer-from-server-on-http-request-in-angular-2) – Jan B. May 30 '17 at 08:34
  • 1
    Possible duplicate of [How do I return the response from an Observable/http/async call in angular2?](https://stackoverflow.com/questions/43055706/how-do-i-return-the-response-from-an-observable-http-async-call-in-angular2) – n00dl3 May 30 '17 at 08:49

2 Answers2

5

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 :)

AT82
  • 71,416
  • 24
  • 140
  • 167
3

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);

Check documentation

kriss
  • 976
  • 17
  • 27
  • Could you provide an example for clarity? This would also be used by others who view this post. – Keeano May 30 '17 at 08:33
  • 1
    @Keeano just did – kriss May 30 '17 at 08:35
  • 1
    This solved my issue and i like your answer compared to how i was looking about it before. I simply did not go slowly enough through the documentation and missed those minor things that matter. – Keeano May 30 '17 at 09:00