Serial and parallel HTTP requests with Angular 5 and RxJS

时间:2018-03-25 19:29:30

标签: angular rxjs

<button (click)="onSaveItems()">Save</button>

this.selectedItems = [ 
  {'id': 1, name: 'A'},
  {'id': 2, name: 'B'},
  {'id': 3, name: 'C'},
  {'id': 4, name: 'D'},
  {'id': 5, name: 'E'}
]

this.apiService1.deleteAllItems()
this.apiService2.addItem(itemId)
this.apiService3.addItemLog(itemId)
this.apiService4.addFlag()

When a user clicks on the Save button, I want to:

  1. Call the apiService1 and delete all items
  2. If step 1 was successful, I want to call apiService2 to add selected item
  3. If step 2 was successful, I want to call apiService3 to add item log for that specific item
  4. Repeat steps 2. i 3. for each item from selectedItems
  5. If all item logs are added successfully i want to call apiService4

(Please note that I can not change APIs logic)

Is there a way to do this with Angular and RxJS?

1 个答案:

答案 0 :(得分:1)

I assume you are using angular http client, and therefore RxJs Observables.

If this is the case, then what you need to do is something along these lines

function processItem(item) {
  return this.apiService2.addItem(item)
          .switchMap(itemId => this.apiService3.addItemLog(item))
}

function deleteAllAndThenProcess() {
  return this.apiService1.deleteAllItems()
             .switchMap(() => Observable.from(this.selectedItems)
             .mergeMap(item => processItem(item))
}

function doEverything() {
   deleteAllAndThenProcess()
   .last(() => this.apiService4.addFlag())
   .subscribe(
     () => console.log('processing completed'),
     err => console.error(error)
   )
}

Details may be wrong (e.g. I have substituted itemId with item as parameter of apiService2.addItem and apiService3.addItemLog, but hopefully this gives an idea on how to chain observables to achieve what you want to achieve. Let me add that this is a typical use case where the power of Observable shines.

You may want to look at this to see more details about a use case which seems pretty similar to yours, even if it talks about node and not Angular.