Angular 7 - последовательные http-вызовы не работают (труба, карта) - PullRequest
0 голосов
/ 27 марта 2019

Я искал и искал, но не могу найти ответ на этот вопрос :-(. Я уверен, что решение связано с ConcatMap или подобным, но я так запутался. Вот мой код:

login(email: string, password: string): Observable<User> {
    const body = new HttpParams()
        .set('email', email)
        .set('password', password);

        return this.http.post<User>(LOGINSERVER, body.toString(),
        {
          headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded')
        })
        .pipe(map(user => {
            // login successful if there's a jwt token in the response
            if (user && user.accessToken) {
                // store user details and jwt token in local storage to keep user logged in between page refreshes
                localStorage.setItem('currentUser', JSON.stringify(user));
                this.currentUserSubject.next(user);

// now go get second set of credentials, the CloudCredentials using the bearer token returned by the first call
                this.http.get<CloudCredential[]>(CLOUDSERVER,
                {
                  headers: new HttpHeaders().set('Authorization', 'Bearer ' + user.accessToken)
                })
                .pipe(map(credentials => {
                    if (credentials) {
                        localStorage.setItem('cloudCredentials', JSON.stringify(credentials));
                        this.cloudCredentialsSubject.next(credentials);
                    }
                }));
    
                    
            }
            return user;
        }));
    }

Так что происходит, что первый http-вызов LOGINSERVER работает!Отлично :-) Однако, когда этот вызов завершается, отладчик Chrome показывает строку, выполняющую секундный http-вызов CLOUDSERVER, но эта конечная точка API никогда не запускается..Pipe.map (), имеющая дело со второй строкой набора результатов выше, никогда не вызывается и не выполняется.

Моя общая цель состоит в том, чтобы приведенный выше метод login () возвращал наблюдаемую величину «User», а также дляметод для установки локальных переменных currentUserSubject и cloudCredentialsSubject для значений этих наблюдаемых, чтобы на них можно было ссылаться позже из остальной части приложения.

Поэтому возникает вопрос: почему second http вызываетсяне выполняется, хотя я вижу, как выполняется строка кода?Что мне нужно сделать, чтобы второй http-вызов выполнялся тогда и только тогда, когда первый вызов завершился успешно?

1 Ответ

3 голосов
/ 27 марта 2019

Вот правильный синтаксис:

return this.http.post<User>(LOGINSERVER, body.toString(), { headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded') }).pipe(
  switchMap(user => {
    if (user && user.accessToken) {
      localStorage.setItem('currentUser', JSON.stringify(user));
      this.currentUserSubject.next(user);

      return this.http.get<CloudCredential[]>(CLOUDSERVER, { headers: new HttpHeaders().set('Authorization', 'Bearer ' + user.accessToken) }).pipe(
        tap(credentials => {
          if (credentials) {
            localStorage.setItem('cloudCredentials', JSON.stringify(credentials));
            this.cloudCredentialsSubject.next(credentials);
          }
        })
      );
    } else {
      return throwError('User is not defined or has no access Token');
    }
  })
);

map используется для преобразования значения вашего потока, в то время как switchMap используется для переключения вашего потока с другим.tap используется для выполнения операции, которая не изменяет поток.throwError выдает ошибку, которая затем может быть перехвачена оператором catchError: она не выдает ошибку как таковую , а скорее позволяет вам переключить ваш действительный поток на недопустимый, переходя ввторой обратный вызов вашей subscribe функции.

Вы можете найти всю информацию об операторах здесь: https://www.learnrxjs.io/operators/

Изучение RxJS требует времени, и лучший способ начать это всегда документация!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...