Many times I faced this issue while trying to be more reactive, I am not able to find a clean way to do it, to make this method returns an Observable.
this is the example code:
public updateItemEligibility(item: Item): void
{
this.updateCalculations(item);
if (item.status == Status.Full)
{
this.markEligibleItem(item);
}
if (item.quantity > 0 && item.Stage == 1)
{
const info: ItemInfo = this.getAdditionalInfoFromApi(); // will uses observable
if (info.Staged)
{
this.updateStagedCalculations(item);
}
}
if (item.quantity == 0 && item.Stage == 2)
{
const stagingInfo: StagingInfo = this.getStaginInfoFromApi();
item.eligible = this.allowStagedItems && item.amount > 0 && stagingInfo.Stages[item.stage].Completed == true;
}
this.updateTotals(item);
}
The problem here is calling the API only if a condition is satisfied.
CodePudding user response:
If I understand your question right, you want a method that returns an Observable that notifies when the item
is updated (if it has to be updated).
If this is the case, then I would proceed as follows (the comments try to explain the logic)
public updateItemEligibility(item: Item): Observable<Item> {
// this initial part is untouched since I guess is all synchronous stuff
this.updateCalculations(item);
if (item.status == Status.Full) {
this.markEligibleItem(item);
}
// here we start the ifs.
if (item.quantity > 0 && item.Stage == 1) {
// In the first case we want to return an Observable
// that notifies after getAdditionalInfoFromApi has returned
// we use the map operator to make this Oservable notify with the item as value
// after performing all necessary things
return this.getAdditionalInfoFromApi().pipe(
map((info: ItemInfo) => {
if (info.Staged) {
this.updateStagedCalculations(item);
this.updateTotals(item);
return item;
}
})
);
}
// here the second if
if (item.quantity == 0 && item.Stage == 2) {
// as we have done above, we return an Observable that notifies when getStaginInfoFromApi returns
// (assuming that getStaginInfoFromApi returns an Oservable) and we use map
// to make the Observable notify with item as value
return this.getStaginInfoFromApi().pipe(
map((stagingInfo: StagingInfo) => {
item.eligible =
this.allowStagedItems &&
item.amount > 0 &&
stagingInfo.Stages[item.stage].Completed == true;
this.updateTotals(item);
return item;
})
);
}
// if none of the conditions above is met, we return an
// an Observable that notifies immediately with item as value
// using the of function
this.updateTotals(item);
return of(item);
}
}
CodePudding user response:
Write method as async
, then you can convert the API call Observable
to Promise
by using the lastValueFrom
method, to execute it like a procedural call.
async updateItemEligibility() {
...
await lastValueFrom(this.getAdditionalInfoFromApi());
...
}
Note:
lastValueFrom
method takes observable andreturn
Promise object.