Головная боль Angular и RxJS Subject с canActivate

У меня есть пример проекта Angular2 с использованием firebase. AuthService использует метод isAuthentificated с субъектом, который возвращает subject.asObserveable.

Метод вызывается дважды:

  • в конструкторе компонента заголовка с помощью подписки, и он передает возвращаемое значение переменной

  • В защите маршрутизатора с помощью first () в canActivate. Примерный проект работает, как ожидалось.

Я переписываю его без FirebaseAPI с моими собственными данными, и он работает, как ожидалось, в компоненте заголовка, но в защите маршрутизатора я всегда получаю пустой объект обратно. Если я использую его так, как в примере проекта, маршрутизатор перестанет работать, поэтому я изменил его, чтобы посмотреть, что произойдет. Это код из authService:

  isAuthenticated() {
const state = new Subject<boolean>();
state.subscribe(x => console.log('Subject start: ' + x));
this.localStorageService.observe('myToken')
  .subscribe((newToken: MyToken) => {
    console.log('localStorageCheck: ' + JSON.stringify(newToken));
    if ((newToken !== null) && (newToken.token !== '')) {
      state.next(true);
    } else {
      state.next(false);
    }
    console.log('state changed');
  });
state.subscribe(x => console.log('Subject subscribe: ' + x));
return state.asObservable();

}

а это код охранника:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
let pass: boolean = false;
const val = this.authService.isAuthenticated().first();
val.subscribe((x:boolean) => {
  console.log('Guard says: ' + x);
  pass = x;
});
// return val;
return pass;

}

в примере проекта только что: return this.authService.isAuthenticated (). first (); Я не вижу разницы в логике и хотел бы понять, чего мне здесь не хватает.

Спасибо

пс. код, также работающий с охраной, выглядит так:

isAuthenticated() {
const state = new Subject<boolean>();
firebase.auth().onAuthStateChanged(function(user) {
  if (user) {
    state.next(true);
  } else {
    state.next(false);
  }
});
return state.asObservable();

}

После еще нескольких тестов я могу заметить, что canActivate запускается, как только тема обновляется в моем проекте, а этого не происходит в примере проекта (хотя тема также обновляется там). Единственная разница в том, что в примере используется наблюдатель из Firebase, а я - из ng2-webstorage. Конечно, я могу обойти это, установив частную переменную вне canActivate, и это сработает.

Я действительно хотел бы понять причину такого различного поведения. Надеюсь, кто-нибудь сможет меня просветить, спасибо.


person Quwax    schedule 14.05.2017    source источник


Ответы (1)


Вы можете вернуть не только логическое значение, но и Observable или Promise в методе canActivate:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
    return this.authService.isUserAuthenticated.isAuthenticated();
}
person karser    schedule 15.05.2017
comment
Я это знаю ;-) Когда я возвращаю наблюдаемое, роутер перестает работать. Мой основной вопрос: как может случиться, что я получаю возвращенный пустой объект, хотя он выглядит как правильный объект, наблюдаемый в отладчике (источник - это субъект), . subscribe не вызывается. Переменная, которую я установил на панели инструментов, всегда правильно обновляется. - person Quwax; 16.05.2017