Angular Вложенный вызов подписки - PullRequest
0 голосов
/ 19 февраля 2020

У меня есть приложение Ionic, и я пытаюсь реализовать модуль Login для этого, используя PHP REST и JWT.

1) Учетные данные типов пользователей и API возвращаются с token

2) Хранение токена в capacitor хранилище и перехват следующего http запроса и добавление токена в заголовок

3) Выполните обратный вызов API и войдите в систему. Информация пользователя

4 ) Сохраните информацию в capacitor хранилище и продолжайте.

Ниже приведен код.

loginAction() {
    if (this.validateInputs()) {
        console.log(this.postData);
        this.authService.login(this.postData).subscribe(
            (res: any) => {
                console.log(res);
                if (res.token) {
                    this.storageService.store('accessToken', res.token);
                    this.authService.getUserProfile().subscribe((profile: any) => {
                        console.log(profile);
                        this.storageService
                            .store(AuthConstants.AUTH, profile)
                            .then(res => {
                                this.router.navigate(['home']);
                            });
                    });
                }
            },
            (error: any) => {
                this.toastService.presentToast('Network Issue.');
            }
        );
    } else {
        this.toastService.presentToast(
            'Please enter email/username or password.'
        );
    }
}

Единственная проблема, с которой я сталкиваюсь - это capacitor и вложенный вызов подписки.

Иногда выполнение для получения profile происходит быстро и перехват возвращает с нулевым значением для accessToken.

Как я могу убедиться, что второй http вызов выполняется только после accessToken правильно хранится?

export class StorageService {
  constructor() {}

  // Store the value
  async store(storageKey: string, value: any) {
    const encryptedValue = btoa(escape(JSON.stringify(value)));
    await Storage.set({
      key: storageKey,
      value: encryptedValue
    });
  }
}

Спасибо

Ответы [ 2 ]

0 голосов
/ 19 февраля 2020

Я обычно использую switchMap для работы с вложенными подписками. Попробуйте:

loginAction() {
  if (this.validateInputs()) {
    console.log(this.postData());
    this.authService.login(this.postData).pipe(
      // switch context from this observable to another observable based on its value
      switchMap((res: any) => {
        console.log(res);
        if (res.token) {
          this.storageService.store('accessToken', res.token);
          return this.authService.getUserProfile();
        } else {
          return of(null); // import of from rxjs
        }
      }),
      filter((profile: any) => !!filter), // don't include the null emissions in the subscribe block
    ).subscribe((profile: any) => {
      console.log(profile);
      this.storageService.store(AuthConstants.AUTH, profile)
          .then(res => {
            this.router.navigate(['home']);
           });
   },
     // can also handle errors using the catchError operator.
     (error: any) => this.toastService.presentToast('Network Issue.');
   );
  } else { 
    this.toastService.presentToast('Please enter email/username or password.');
  }
}
0 голосов
/ 19 февраля 2020

Отредактируйте функцию storageService.store(), чтобы вернуть Storage.set. Согласно документам , он возвращает Обещание. Затем вы можете применить .then к вашему вызову и обрабатывать ваши операции в обратных вызовах.

export class StorageService {
  constructor() { }

  // Store the value
  public store(storageKey: string, value: any): any {
    const encryptedValue = btoa(escape(JSON.stringify(value)));
    return Storage.set({ key: storageKey, value: encryptedValue });
  }
}

А внутри вашей функции loginAction ():

if (res.token) {
  this.storageService.store('accessToken', res.token).then(
    data => {
      this.authService.getUserProfile().subscribe((profile: any) => {
          console.log(profile);
          this.storageService
            .store(AuthConstants.AUTH, profile)
            .then(res => { this.router.navigate(['home']); });
      });
    },
    error => { // handle error }
  );
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...