MIP1983
MIP1983

Reputation: 1374

How to pass a property in an angular components as an argument to a private function

I've got an angular component that calls via http to an API to populate a select list. The property on this component looks like this:

searchKeys: SelectItem[];

And the function that gets the data onInit that works just fine:

private GetSearchKeyList() {
    this._httpService.get('/api/List/Key')
        .map(result => result.json())
        .subscribe(list => {
            this.searchKeys = list.map(item => { 
                return { label: item.text, value: item.value };
              });
        });
}

Now, I'd like to turn it into something more generic that I can use for other properties, so something like this:

this.LoadListValues('/api/List/Key', this.searchKeys);
private LoadListValues(apiEndpoint: string, projectTo: SelectItem[]) {
    this._httpService.get(apiEndpoint)
    .map(result => result.json())
    .subscribe(list => {
        projectTo = list.map(item => { 
            return { label: item.text, value: item.value };
          });
    });
}

But this doesn't seem to work, where I'm passing 'projectTo' as a reference to the property on my component, it's never populated with values.

What am I missing here?

Upvotes: 1

Views: 1053

Answers (1)

Suraj Rao
Suraj Rao

Reputation: 29614

According to this answer, Javascript does call by sharing. So the parameter passed is unaffected in your case since you are changing the value of it.

Secondly, observables are asynchronous and so setting of the value within subscribe method may occur after you try to access the data. So something like the following which was suggested in the comments is also likely to fail.

private LoadListValues(apiEndpoint: string, projectTo: SelectItem[]) {
    this._httpService.get(apiEndpoint)
    .map(result => result.json())
    .subscribe(list => {
        list.map(item => { 
            projectTo.push({ label: item.text, value: item.value });
          });
    });
}

One way is to return everything as an Observable<any[]> and later subscribe from the common private function.

private LoadListValues(apiEndpoint: string):Observable<any[]>{
   return this._httpService.get(apiEndpoint)
    .map(result => result.json())
    .map(list => list.map(item => return { label: item.text, value: item.value });

}

This would allow you to manipulate the array in a generic way without passing any array parameter.

Upvotes: 1

Related Questions