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.
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);
}
}