Ошибка при использовании mergeMap для объединения двух последовательных подписок в Angular - PullRequest
0 голосов
/ 17 октября 2018

У меня есть две последовательные подписки:

 this.authService.tokenObs.pipe( map(res => res),mergeMap( token =>
    this.service.getUsers(token).subscribe(res2=>{
            console.log('res2', res2)
  })
));

Я получаю сообщение об ошибке для параметра токена в карте слияния:

Аргумент типа '(token: {}) => Подписка'нельзя назначить параметру

типа' (значение: {}, индекс: число) => ObservableInput <{}> '.

Тип "Подписка" не может быть назначена типу "ObservableInput <{}> '.

Типу «Подписка» нельзя присвоить типу «ArrayLike <{}>».

Свойство «длина» отсутствует в типе «Подписка».(параметр) token: {}

Я впервые использую mergeMap, поэтому не знаком с этой ошибкой.

Ответы [ 2 ]

0 голосов
/ 17 октября 2018

Если вы хотите, чтобы последовательность Observables зависела друг от друга, возможно, вам лучше использовать «switchMap»:

import { switchMap } from 'rxjs/operators';

this.authService.tokenObs.pipe(
   switchMap((token) => {
      return this.service.getUsers(token);
   }),
   map((user) => {
      // do what you want;
   })
)

Также вы можете использовать «mergeMap»:

import { mergeMap} from 'rxjs/operators';

this.authService.tokenObs.pipe(
   mergeMap((token) => {
      return this.service.getUsers(token);
   }),
   map((user) => {
      // do what you want;
   })
)

Разницаявляется то, что если this.authService.tokenObs изменяется, «switchMap» отменяет ожидающий запрос к серверу (this.service.getUsers (token)).Но «mergeMap» не отменит, а продолжит свое выполнение.PS: попробуйте исследовать и начните использовать @ ngrx-store для лучшей архитектуры системы с Observables: https://github.com/ngrx/platform

0 голосов
/ 17 октября 2018

Вам нужно изменить свой код, как показано ниже

this.authService.tokenObs.pipe(
     map(res => res),
     mergeMap(this.service.getUsers(token))
).subscribe(res2=>{
    console.log('res2', res2)
});

Поскольку вы новичок в этом, можете взглянуть на рабочий пример https://stackblitz.com/edit/angular-gsefpz

import { Component } from '@angular/core';
import { map, mergeMap } from 'rxjs/operators';
import { HttpClient} from '@angular/common/http';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  name = 'Angular';

  constructor(public http: HttpClient) {
    this.http.get('https://jsonplaceholder.typicode.com/users').pipe(
      map(res => res[0].id),
      mergeMap(id => this.http.get(`https://jsonplaceholder.typicode.com/posts?userId=${id}`))
    ).subscribe(res2 => {
      console.log('res2', res2)
    });
  }
}

РЕДАКТИРОВАТЬ 2:

https://stackblitz.com/edit/angular-gsefpz

Обновлен код для обработки ошибки.Проверьте ошибку, если вы изменили ее на неверный URL.

import { Component } from '@angular/core';
import { map, mergeMap, tap, catchError } from 'rxjs/operators';
import { throwError } from 'rxjs';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  name = 'Angular';

  constructor(public http: HttpClient) {
    this.http.get('https://jsonplaceholder.typicode.com/users').pipe(
      tap(data => console.log('data >>> ', data)),
      map(res => res[0].id),
      tap(data => console.log('transformed data >>> ', data)),
      mergeMap(id => this.http.get(`https://jsonplaceholder.typicode.com/posts?userId=${id}`)),
      catchError(error => {
        console.log('ERROR >>>> ', JSON.stringify(error));
        return throwError({ status: error.status, errorMsg: error.statusText });
      })
    ).subscribe(res2 => { console.log('res2', res2) }, err => console.log(err));
  }
}

РЕДАКТИРОВАТЬ 3 для rxjs 5,5 https://stackblitz.com/edit/angular-5-tutorial-yzowvt

import { Component } from '@angular/core';
import {HttpClient} from '@angular/common/http';
import { Observable } from 'rxjs';

  constructor(public http: HttpClient) {
    this.http.get('https://jsonplaceholder.typicode.com/users')
    .do(data => console.log('data >>> ', data))
    .map(res => res[0].id)
    .do(data => console.log('transformed data >>> ', data))
    .mergeMap(id => this.http.get(`https://jsonplaceholder.typicode.com/posts?userId=${id}`))
    .catch(error => {
        console.log('ERROR >>>> ', JSON.stringify(error));
        return Observable.throw({ status: error.status, errorMsg: error.statusText });
    })
    .subscribe(res2 => { console.log('res2', res2) }, err => console.log(err));
  }
...