2

I have a method which needs to return an Observable. This observable is then fed to a third party component as input. We can not modify the third party component.

The problem that I am facing here while returning the desired observable is that I need to perform some computation on the result and this computation is dependent on another service call (_transService.getTransactions) which can only be executed after first service call.

How can I modify the the result of first service call before returning it as observable (Observable < searchResult > ).

Currently in the code below it cannot wait for call to finish and return empty data.

public search(): Observable<Response<ListDetail>> { let searchResult: Response<ListDetail>; let gridData: ListDetail[] = []; this.post(`search`) .pipe( filter((response: Response<ListDetail>): boolean => response && response.status === 'Success'), mergeMap( (res: Response<ListDetail>): Observable<Response<Transactions[]>> => { searchResult = res; gridData = res.content.items; const ids = res.content.items.map((result: ListDetail) => result.id); return this._transService.getTransactions(ids); } ) ) .subscribe((res: Response<Transactions[]>) => { const transactionsList = res.content; gridData.forEach((item: ListDetail) => { item.transactions = []; transactionsList.forEach((result: Transactions) => { const transactions = result?.transactions; transactions.forEach((transaction: Transaction) => { if (transaction.parentId === 0) { item.transactions.push(transaction); if (transaction.transactionType === 'CASH') { if (!item.cashAmount) { item.cashAmount = 0; } item.cashAmount+= transaction.amount; } } }); }); }); }); return of(searchResult); } 

2 Answers 2

3

Try this.

public search(): Observable<Response<ListDetail>> { let searchResult: Response<ListDetail>; return new Observable<Response<ListDetail>>(observer => { let gridData: ListDetail[] = []; this.post(`search`) .pipe( filter((response: Response<ListDetail>): boolean => response && response.status === 'Success'), mergeMap( (res: Response<ListDetail>): Observable<Response<Transactions[]>> => { searchResult = res; gridData = res.content.items; const ids = res.content.items.map((result: ListDetail) => result.id); return this._transService.getTransactions(ids); } ) ) .subscribe((res: Response<Transactions[]>) => { const transactionsList = res.content; gridData.forEach((item: ListDetail) => { item.transactions = []; transactionsList.forEach((result: Transactions) => { const transactions = result?.transactions; transactions.forEach((transaction: Transaction) => { if (transaction.parentId === 0) { item.transactions.push(transaction); if (transaction.transactionType === 'CASH') { if (!item.cashAmount) { item.cashAmount = 0; } item.cashAmount+= transaction.amount; } } }); }); }); observer.next(searchResult); observer.complete(); }); }); } 
Sign up to request clarification or add additional context in comments.

Comments

1

The other option is to use tap:

public search(): Observable<Response<ListDetail>> { return new Observable<Response<ListDetail>>(observer => { let gridData: ListDetail[] = []; this.post(`search`) .pipe( filter((response: Response<ListDetail>): boolean => response && response.status === 'Success'), tap( res => { observer.next(res); observer.complete(); }), mergeMap( (res: Response<ListDetail>): Observable<Response<Transactions[]>> => { searchResult = res; gridData = res.content.items; const ids = res.content.items.map((result: ListDetail) => result.id); return this._transService.getTransactions(ids); } ) ) .subscribe((res: Response<Transactions[]>) => { const transactionsList = res.content; gridData.forEach((item: ListDetail) => { item.transactions = []; transactionsList.forEach((result: Transactions) => { const transactions = result?.transactions; transactions.forEach((transaction: Transaction) => { if (transaction.parentId === 0) { item.transactions.push(transaction); if (transaction.transactionType === 'CASH') { if (!item.cashAmount) { item.cashAmount = 0; } item.cashAmount+= transaction.amount; } } }); }); }); }); }); } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.