I have a service declared in angular with the getSomeData() method in which I collect data from a json like so:
import { Injectable } from '@angular/core';
import {Http} from '@angular/http';
import { HttpModule } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import "rxjs/add/operator/map";
import "rxjs/add/operator/filter";
@Injectable()
export class GetDataService {
constructor(private http: Http) { }
getSomeData() {
return this.http.get("dataTable.json")
.map(res => res.json());
}
}
In the component I have a variable data : any;
to paint the data in the template.
When calling the subscribe service in the component with a normal javascript function like so, it doesn't show me the data with the response.
ngOnInit():void {
this._service.getSomeData().subscribe(
function(response) { this.data = JSON.stringify(response) },
function(error) { console.log("Error happened" + error)},
function() { console.log("the subscription is completed")}
);
}
However if I call the subscribe method with an Arrow Function if it paints the data:
ngOnInit():void {
this._service.getSomeData().subscribe(
response=>{
this.data = JSON.stringify(response);
}
err=>{
console.log("Error happened" + error)
}
);
}
I think it is a matter of asynchrony since with normal functions it does not have time to paint the data.
The difference between an arrow function and a normal one is the context: In classic functions the context is defined when calling them and in arrow functions it is defined when declaring them. Nothing better than an example to see it clearly:
Explanation: getA is a normal function, so if it's called as a function,
this
it's the context it's called in, but if it's called as a method,this
it's the object the method belongs to.Instead, getB is an arrow function, so
this
it is always the context in which it was declared.In your case, since your functions are declared when the context is your class
GetDataService
, itthis
will point to the instance ofGetDataService
, while traditional functions this will be the context of the observable, sothis.data
it can't be assigned because it doesn't exist.How to make "classic" functions work in this scenario? There are two solutions: