Получение ошибок, пытающихся получить наблюдаемые из "цепи наблюдаемых" - PullRequest
0 голосов
/ 08 июня 2018

Хорошо.У меня есть некоторый асинхронный код в моем Angular-компоненте, который работает просто отлично.Выглядит так (кратко):

export class SomeComponent {

    user: User;
    /* ... */
    email: string;
    /* ... */

    private someMethod(): void {
      /* some code here */
      this.userService1.getUsers().subscribe(users => {
        users.forEach(user => {
          if (user.email && user.email === this.email) {
             this.userService2.getUser(user.id).subscribe(foundUser => {
               let someFields;
               if (foundUser) {
                 someFields = (({ field1, field2 }) => ({ field1, field2 }))(foundUser); 
               }
               this.user = {...user, ...someFields};
             });
           }
         });
      });
      /*some code here */              
    }
 }

Я пропускаю некоторые типы и называю переменные немного неловко (но просто), потому что это не главное.Код работает.Но Я хочу инкапсулировать процесс построения пользователя (из 2 сервисов), потому что он мне понадобится в разных компонентах.Я пытался, но ...

constructUser(email): Observable<IUser> {
  let finalUser: IUser;

  return this.userService1.getUsers().merge(users => {
    return users.filter(user => {
      if (user.email && user.email === email) {
        return this.userService2.getUser(user.id).map(foundUser => {
          let someFields;
          if (foundUser) {
            someFields = (({ field1, field2 }) => ({ field1, field2 }))(foundUser); 
          }
          finalUser =  {...user, ...someFields};

          return Observable.of(finalUser);
        });
      }
    });
  });
}

Мой WebStorm не показывает ошибки.Но в консоли я получаю this.userService1.getUsers (...). Слияние не является функцией .

я пробовал слияние , concat , flatMap , как угодно - но все равно безуспешно.Единственная разница была в ошибках, которые я получил.У меня нет большого опыта работы с rxjs, поэтому я застрял.Буду очень признателен за любую помощь или подсказки.

UPD.
Решено, но в течение 7 дней (пока активна награда) любой по-прежнему приветствует более краткие и функциональные решения:)

Ответы [ 3 ]

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

Я думаю, что-то вроде этого - то, что вы хотите:

RxJs 5:

import 'switchMap' from 'rxjs/add/operator/switchMap';
import 'map' from 'rxjs/add/operator/map';


this.userService1.getUsers()
    .map(users => users.find(userInList => userInList.email === "SomeEmail")) //Map the observable with users to a single user
    .switchMap(user => this.userService2.getUser(user.id)) //Map the observable by an other observable
    .subscribe(...doSomething with the result)

RxJs 6:

import {map, switchMap} from 'rxjs/operators';

this.userService1.getUsers().pipe(
    map(users => users.find(userInList => userInList.email === "SomeEmail")), //Map the observable with users to a single user
    switchMap(user => this.userService2.getUser(user.id)) //Map the observable by an other observable
).subscribe(...doSomething with the result)
0 голосов
/ 13 июня 2018

Правильный ответ (пропуская некоторые типы и изменяя реальные имена переменных):

Большое спасибо @Robin Dijkhof, который дал мне операторов rxjs в правильной последовательности .

public constructUser(email: string): Observable<User> {
  return this.userService1.getUsers().pipe(
    map(users => users.find(userInList => userInList.email === email)),
    switchMap(user => {
      return this.userService2.getUser(user.id).map(foundUser => {
        if (foundUser) {
          return {...user, ...(({ field1, field2 }) => ({ field1, field2 }))(foundUser)};
        } else {
          return {...user};
        }
      });
    })
  );
}

И теперь я могу легко использовать этот метод для захвата созданного пользователя по электронной почте (возможно, позже я заменю электронную почту идентификатором) в любом компоненте, например:

this.myHelperService.constructUser(email).subscribe(user => {...});

Я думаю, что можно сделать решение еще более функциональным и лаконичным (и, возможно, решение должно быть более надежным) ...
Итак!Любой желающий, 50 дополнительных бонусных баллов по-прежнему здесь в течение 7 дней =)

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

Я думаю, что вы должны подписаться, прежде чем делать что-либо еще

this.userService1.getUsers().subscribe(users => {...
...