In order to assign the value of a local variable through delegation, you will need to either provide a callback function (similar to how you currently do in your subscribe
method) or specify the property name that needs to be updated.
The effort saved by making it generic is minimal unless there is some repeated code, which is not present in your example.
If you truly wish to create a generic function, consider these approaches:
Using a Callback
The object returned from the observable is of a generic type. The callback function takes a single argument of the same type.
loadData<T>(serviceMethod: Observable<T>, action: (value: T) => void) {
serviceMethod.subscribe((res: T) => action(res));
}
You can invoke this function as follows:
this.loadData(this.myServiceOne.getDataOne(), res => this.variableOne = res);
Using Property Name
TKey
must be a named key within AppComponent
.
TValue
represents the type of the named key and the type of object returned by the observable.
loadData2<TKey extends keyof AppComponent, TValue extends AppComponent[TKey]>(
serviceMethod: Observable<TValue>,
key: TKey
): void {
const component: AppComponent = this;
serviceMethod.subscribe((res: TValue) => {
component[key] = res;
});
}
You can call this function like so:
this.loadData(this.myServiceOne.getDataOne(), 'variableOne');
Using Fully Generic Property Name
T
represents the component type.
TKey
must be a named key within T
.
TValue
represents the type of the named key and the type of object returned by the observable.
loadData2<T, TKey extends keyof T, TValue extends T[TKey]>(
component: T,
serviceMethod: Observable<TValue>,
key: TKey
): void {
serviceMethod.subscribe((res: TValue) => {
component[key] = res;
});
}
You can use this function as shown below:
this.loadData(this, this.myServiceOne.getDataOne(), 'variableOne');
Using Promises
You could also convert the observable to a promise and utilize async/await, but this may not be necessary.
DEMO: https://stackblitz.com/edit/angular-btfqng