Angular 5 - Служба не обновляет подписанную переменную

Я новичок в Angular..

У меня есть AuthService в моем веб-приложении, которое аутентифицирует пользователей через Angularfire2 (firebase) и вставляет электронную почту и флаг (указывающий, заполнил ли пользователь форму данных профиля) в базу данных firebase.

Моя защита маршрута проверяет, аутентифицирован ли пользователь и заполнил ли пользователь форму данных профиля, если нет, я перенаправляюсь на форму данных профиля. Если пользователь уже заполнил форму, я перенаправляюсь на страницу надежды.

Я получаю информацию о том, заполнил ли пользователь форму основных данных через службу UserData:

  constructor(private afd: AngularFireDatabase, private authService: AuthService) {

  }

  isProfileComplete (): Observable<any> {
    return this.afd.list(`/users/${this.authService.uid}`)
            .snapshotChanges()

  }

Затем в authGuard я делаю логику, чтобы направить пользователя:

 constructor(private authService: AuthService,
              private router: Router,
              private usrData: UserDataService) {}

  canActivate( route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {

    if (this.authService.isAuthenticated())  {
      console.log(this.usrData.isProfileComplete())
      this.usrData.isProfileComplete()
      .map(userInfos => {
        console.log(userInfos)
           userInfos.forEach(item => {
            console.log(userInfos)
            if ((item.payload.key === 'profileComplete') && (item.payload.val() === true)) {
              console.log('user is logged in & data form completed')
              return true;
            } else if ((item.payload.key === 'profileComplete') && (item.payload.val() !== true)) {
              this.router.navigate(['data_form']);
              console.log('user logged in not completed the form')
              return false;
            }
      })

      })

    }  else {
        this.router.navigate(['login']);
        console.log('user is not logged in ')
        return false;
    }
}

Я думаю, что код не достигает раздела map observable для чтения значений ключа profileComplete.

Может ли кто-нибудь указать мне правильное направление, пожалуйста?

Спасибо


person sheeni    schedule 11.05.2018    source источник


Ответы (2)


Возвращает ли следующее Observable?

this.usrData.isProfileComplete()

Несмотря на это, вы возвращаете true/false из контекста вашего цикла forEach, что означает, что метод внешней карты ничего не возвращает.

Возможно, вы захотите рассмотреть возможность использования find, а не forEach, тогда вы можете вернуть результат того, нашел ли что-нибудь find:

return !!userInfos.find(item => (item.payload.key === 'profileComplete') 
                                && (item.payload.val() === true));

Очевидно, что это не относится к случаю перенаправления, когда вы хотите вернуться к форме, но должно указать вам правильное направление.

person Chris White    schedule 11.05.2018
comment
Привет Крис, спасибо за ответ. К сожалению, похоже, что код не достигает элемента (!!userInfos.find(item =› ) во время работы. Я добавил console.log чуть выше возврата, и вывода не было. re:this.usrData.isProfileComplete( ) да, он возвращает Observable‹any›, я также добавил код, сгибающий его выше. - person sheeni; 11.05.2018
comment
вам также нужно ключевое слово return в операторе карты. - person Chris White; 11.05.2018
comment
отлично спасибо - person sheeni; 11.05.2018

Вы должны вернуть этот тип Observable<boolean> | Promise<boolean> из CanActivate. Потому что JavaScript не ждет обратных вызовов. Пример:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {

if (this.authService.isAuthenticated()) {
  console.log(this.usrData.isProfileComplete())
  return this.usrData.isProfileComplete()
    .map(userInfos => {
      console.log(userInfos)
      userInfos.forEach(item => {
        console.log(userInfos)
        if ((item.payload.key === 'profileComplete') && (item.payload.val() === true)) {
          console.log('user is logged in & data form completed')
          return of(true);
        } else if ((item.payload.key === 'profileComplete') && (item.payload.val() !== true)) {
          this.router.navigate(['data_form']);
          console.log('user logged in not completed the form')
          return of(false);
        }
      })

    })

} else {
  this.router.navigate(['login']);
  console.log('user is not logged in ')
  return of(false);
}

}

person Abylay    schedule 11.05.2018
comment
Привет, Абылай, я внес предложенное тобой изменение и, к сожалению, все тот же результат. - person sheeni; 11.05.2018
comment
Я хотел вернуть Observable, пример был подсказкой. Я вижу, вы нашли решение, отлично! - person Abylay; 11.05.2018