Почему asyn c pipe не обнаруживает изменения в Angular (а подписка в component.ts делает)? - PullRequest
0 голосов
/ 02 февраля 2020

Я использую асин c канал в angular для мониторинга наблюдаемого, поступающего из магазина rx js. NgOnInit компонента выглядит следующим образом

ngOnInit() {
  this.userRole$ = this.store.select(selectUserProfile).pipe(
    filter(user => !!user),
    map(user => parseUserRole(user.role))
  );
}

Шаблон компонента выглядит следующим образом

<p> User role is {{ userRole$ | async }} </p>

После входа в систему сообщение на странице остается пустой строкой

В component.ts я добавил следующий код для отладки проблемы

this.userRole$.subscribe(userRole => {
  alert(`new user role is ${userRole}`);
});

После того, как пользователь войдет в систему, я получу предупреждение о том, что «новая роль пользователя - admin», однако канал в html шаблон не обновляется.

Когда я заменил store select () на фиктивное значение с использованием of (), и все заработало, как и ожидалось, так что я почти уверен, что проблема связана с rx js.

Редуктор аутентификации (который запускается) выглядит следующим образом (

export function reducer(state = initialAuthState, action: AuthActions): AuthState {
    switch (action.type) {
        /// ...CODE OMITTED
        case AuthActionTypes.UserProfileRetrieved:
            alert(`setting user profile ${action.payload.userProfile}`)
            return { ...state, userProfile: action.payload.userProfile }
        default:
            return state;
    }
}

Я пытался убедиться, что действие UserProfileRetrieved отправлено изнутри ngZone.run () но это не имело значения. Я действительно не знаю, как еще go об отладке этого. Любые указатели будут с благодарностью. Спасибо!

Ответы [ 2 ]

1 голос
/ 02 февраля 2020

Можете ли вы попробовать этот код и посмотреть, работает ли он нормально. Добавили оператор касания, чтобы увидеть, имели ли место такие изменения / данные, отправленные из магазина.

this.userRole$ = this.store
   .select(selectUserProfile)
   .pipe(
     tap(user => console.log('FETCHED:', user)),        // Console if user data exists
     filter(Boolean),                                   // Change !!user to Boolean
     tap(user => console.log('FILTERED:', user)),       // Console if user exists after filter 
     map(user => parseUserRole(user.role))
     tap(user => console.log('MAPPED:', user)),         // Console if user is mapped
   );

ПРИМЕЧАНИЕ:

То, что магазин отправит свой ответ только один раз до / родительский сервис вызывается.

Пример:

// If along with the getUsers() functionality has a piped storeService in it
// http.get(url).pipe(tap(data => this.storeService.set('users', data)))
this.userService.getUsers().subscribe();    

// You can then initialize your store to get the data invoked/set above
this.user$ = this.store.select('users');
0 голосов
/ 04 февраля 2020

Оказалось, что это вызвано побочным эффектом потока входа в систему собственного приложения auth0. Маршрутизатор приложения был настроен на использование маршрутизации на основе ha sh для поддержки Cordova. После получения токена входа от auth0 мы очищали ha sh для удаления информации токена. Любые обновления магазина после этой точки не отражались в асинхронных каналах c, но обновления до этого были.

Если у кого-то возникла подобная проблема, убедитесь, что очистка ha sh последнее, что вы делаете перед переходом на URL авторизации поста . Спасибо @Shorbagy и @KShewengger за вашу помощь.

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