RxJS / Angular 7: разветвление с различными обратными вызовами - PullRequest
0 голосов
/ 12 марта 2019

Я в некотором роде новичок в rxjs (мы долго зависали с angularJS и наконец-то избавились от нашего технического долга).

Используя angular7, у меня есть список таких запросов.Используя forkJoin, я управляю им так:

let requests = []
for (let asset in this.assets)
{
    if(asset.enabled)
        requests.push(this.apiService.postAsset(oAsset))
}
return forkJoin(requests)

И все работает нормально, я получаю массив ответов. однако Я немного застрял, пытаясь понять, как получить различные обратные вызовы в зависимости от типа ресурса.Я хотел бы что-то вроде

private saveAssets(): Observable<any>{
    let requests = []
    for (let asset in this.assets)
    {
      //asset exists already
      if(asset.id)
      {
        requests.push(this.apiService.putAsset(asset)
          .subscribe(response => {
           // do something with asset
          }))
      }
      else
      {
        requests.push(this.apiService.postAsset(asset)
          .subscribe(response => {  
            asset.id = response.id
            // do some more thing with asset
          }))
      }
    }
    return forkJoin(requests)
    //keep the forkjoin because I want to do something when everything is done
}

Но это не сработает.Ошибка ERROR TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable. связана с вызовом функции, выполняющей запрос, который выглядит следующим образом (он работал без единой подписки):

this.saveAssets()
    .subscribe(responses => {
        console.log(responses)
    })

Любая помощь или подсказка о том, что искать, был бы очень признателен ... Я уделю больше времени изучению RxJS, но сейчас я просто пытаюсь заставить эту маленькую вещь работать не слишком грязно.

Большое спасибо!

1 Ответ

2 голосов
/ 12 марта 2019

Подписка на наблюдаемое вернет подписку. Но форк-джойн будет ожидать массив наблюдаемых. В вашем случае это будет массив подписок. Используйте оператор map для каждого запроса следующим образом, чтобы решить вашу проблему.

let requests = []
for (let asset in this.assets)
{
  //asset exists already
  if(asset.id)
  {
    requests.push(this.apiService.putAsset(asset)
      .pipe(map(response => {
           // do something with asset or alter the response from here
          return response; 
         })
        ));
  }
  else
  {
    requests.push(this.apiService.postAsset(asset)
       .pipe(map(response => {
         // do something with asset or alter the response from here
         return response; 
      })));
  }
}
return forkJoin(requests).

Оператор карты применяет выбранную вами функцию к каждому элементу. испускается источником Observable и возвращает Observable, который испускает результаты этих функций приложений.

Если вы не хотите изменять конечный результат, используйте tap operator.

...