Keeano
Keeano

Reputation: 308

Angular 2 Service not updating to component

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

Answers (2)

AVJT82
AVJT82

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

kriss
kriss

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

Check documentation

Upvotes: 3

Related Questions