Reputation: 1672
I have a service that is called in a component and it was working before I tried to implement some code reuse tactics, but now the http client isn't coming in as defined. The component calls the appropriate function like this:
//actions object that maps the request on the object
//split between the different areas of the app.
serviceActions: {[name: string]: {[name: string]:(...args: any[]) => Observable<any>}} = {
'Customer':{
GetCategories: this._service.GetCategories,
}
'Admin':{...}
};
// source string referenced in the function call
source: string = 'Customer';
//the actual call being made
this.serviceActions[this.Source].GetCategories(...).subscribe(...)
This code is calling a function on a service that takes http
as a parameter:
//service constructor:
constructor(private httpClient: Http) { }
//service method:
public GetCategories(showAll = false, parentId = 0): Observable<Array<SelectModel>> {
let link = AppSettings.API_COMMON_CATEGORIES;
let params: URLSearchParams = new URLSearchParams();
params.set('showAll', showAll.toString());
params.set('parentId', parentId != null ? parentId.toString() : null);
let requestOptions = new RequestOptions();
requestOptions.search = params;
return this.httpClient.get(link, requestOptions).map(response => {
let result = JSON.parse(response.json());
let list = new Array<SelectModel>();
let caregories: Array<any> = result;
caregories.forEach(category => {
list.push(this.CreateSelectModel(category));
});
return list;
});
}
This was working fine when the service method was called directly, but now that I've implemented the serviceActions
object, it's saying cannot read property get of undefined
what gives?
Upvotes: 0
Views: 1755
Reputation: 1672
The issue stems from the fact that packing functions on the object dereferences this
from the class where it was defined. To get around this, we should wrap the function package in another anonymous function passing along the parameters.
So instead of:
serviceActions: {[name: string]: {[name: string]:(...args: any[]) => Observable<any>}} = {
'Customer':{
GetCategories: this._service.GetCategories,
}
'Admin':{...}
};
it should really be:
serviceActions: {[name: string]: {[name: string]:(...args: any[]) => Observable<any>}} = {
'Customer':{
GetCategories: (params) => this._service.GetCategories(params),
}
'Admin':{...}
};
to preserve the reference to this
in the class.
Upvotes: 1