Возврат наблюдаемой путем сопоставления другой наблюдаемой - PullRequest
0 голосов
/ 12 июня 2018

Я пытаюсь отобразить наблюдаемую информацию, получить значение из моей возвращаемой наблюдаемой, затем передать это значение в другую наблюдаемую и вернуть этот результат.Вот что у меня есть:

  getJobsByUser(user: User): Observable<Job[]> {
    return this.getUsersGroupsAsObservable(user.uid, 'contacts').map(groups => {
      groups.map(group => {
        this.getJobsbyGroup(group.id);
      });
    });

  getJobsbyGroup(groupId: string): Observable<Job[]> {
    return this.afs
      .collection<Job>('jobs', ref => ref.where(`group.${groupId}`, '==', true))
      .valueChanges();
  }

  getUsersGroupsAsObservable(
    userId: string,
    type: string = 'users',
  ): Observable<Group[]> {
    return this.afs
      .collection<Group>('groups', ref =>
        ref.where(`${type}.${userId}`, '==', true),
      )
      .valueChanges();
  }

Проблема заключается в том, что машинопись показывает, что моя функция getJobsByUser будет возвращать наблюдаемое типа: void.Когда я вывожу его на свой шаблон, я ничего не получаю или не определяю.Я чувствую, что мне нужно использовать switchMap, но я немного размыт с rx / js.Я не уверен, как вернуть Observable типа Job []

Обновление: с помощью @Pranay Rana я сейчас возвращаю массив и могу получить первое значение, например:

  getJobsByUser(user: User): Observable<Job[]> {
    return this.getUsersGroupsAsObservable(user.uid, 'contacts').pipe(
      mergeMap(groups => {
        // returns an array of groups - we need to map this
        return this.getJobsbyGroup(groups[0].id); // works with the first value - do we need another map here?
      }),
    );
  }

Обновление 2: Мне удалось получить некоторые данные из хранилища, но он генерирует несколько наблюдаемых, а не объединенный поток:

this.fb.getUsersGroupsAsObservable(user.uid, 'contacts')
   .switchMap(groups => {
      return groups.map(group => this.fb.getJobsbyGroup(group.id));
   })
    .subscribe(res => {
       console.log(res);
       // this emits multiple observables rather than one
       this.job$ = res;
    });

Ответы [ 2 ]

0 голосов
/ 12 июня 2018

Хорошо, сначала вы пропустили два оператора return в функции getJobsByUser (показано ниже с заглавной буквы RETURN:

getJobsByUser(user: User): Observable<Job[]> {
    return this.getUsersGroupsAsObservable(user.uid, 'contacts').map(groups => {
      RETURN groups.map(group => {
        RETURN this.getJobsbyGroup(group.id);
      });
    });

Или, что более элегантно:

getJobsByUser(user: User): Observable<Job[]> {
    return this.getUsersGroupsAsObservable(user.uid, 'contacts')
      .map(groups => groups.map(group => this.getJobsbyGroup(group.id)));
}

Теперь нам нужно сгладить результат, потому что, если я правильно понял, 1 user имеет много groups и каждый group много jobs, и вы хотите, чтобы ваш конечный результат был просто Job[] со всеми jobs из всех groups из user.

Вы можете использовать несколько операторов, чтобы сгладить результаты, например, switchMap или concatMap. Вот пример:

getJobsByUser(user: User): Observable<Job[]> {
    return this.getUsersGroupsAsObservable(user.uid, 'contacts')
      .concatMap(groups => groups)
      .concatMap(group => this.getJobsbyGroup(group.id))
      .concatMap(jobs => jobs)
      .toArray();
}

В каждой строке указано следующее:

  1. Получите мне groups для user // возвращает Observable<Group[]>
  2. Сгладьте результатGroup[] // возвращает Observable<Group>
  3. Получите мне jobs для group // возвращает Observable<Job[]>
  4. Сгладьте результат job[] // возвращает Observable<Job>
  5. Соберите все события Job в одно событие с Job[]
0 голосов
/ 12 июня 2018

Ниже описан подход, подробно рассмотренный по адресу: Способ обработки параллельных множественных запросов

Нижеприведенный подход использует mergemap

getJobsByUser(user: User) {
     return this.getUsersGroupsAsObservable(user.uid, 'contacts').pipe(
       mergeMap(group => this.getJobsbyGroup( group.id))
     );
}

callingfunction(){
  const requests = this.getJobsByUser(this.user);
  requests.subscribe(
  data => console.log(data), //process item or push it to array 
  err => console.log(err));
}

, вы также можете использоватьиз forkJoin

getJobsByUser(user: User) {
         return this.getUsersGroupsAsObservable(user.uid, 'contacts').pipe(
           map(group => this.getJobsbyGroup( group.id))
         );
    }

    callingfunction(){
      const requests = forkJoin(this.getJobsByUser(this.user));
      requests.subscribe(
      data => console.log(data), //process item or push it to array 
      err => console.log(err));
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...