I am relatively new to NGRX and I am attempting to set up a basic NGRX example. In my project, I have an interface named LoginState, which serves as the Object in my Store. Inside the LoginState, there is a user object of type IUser. Whenever I try to select this object in my component, I do not receive the IUser when the user object undergoes changes (although my effects appear to be functioning correctly, as subscribing directly to the store returns all state changes).
Here is how I have configured everything:
app.module.ts
imports: [
...
StoreModule.forRoot({loginState: loginReducer})
]
login.actions.ts
export const userLoginRequest = createAction('[Login] user login request');
export const userLoginFacebookSuccess = createAction('[Login] user login facebook success', props<{socialUser: SocialUser}>());
export const userLoginSuccess = createAction('[Login] user login success', props<{user: IUser}>());
login.reducer.ts
export interface LoginState {
request: boolean;
socialUser?: SocialUser;
user?: IUser;
}
export const initialState: LoginState = {
request: false
};
const reducer = createReducer(initialState,
on(userLoginRequest, (state, action) => ({
...state,
request: true
})),
on(userLoginFacebookSuccess, (state, action) => ({
...state,
socialUser: action.socialUser
})),
on(userLoginSuccess, (state, action) => ({
...state,
user: action.user
}))
);
export function loginReducer(state: LoginState, action: Action): LoginState {
return reducer(state, action);
}
login.effects.ts
import { userLoginRequest, userLoginSuccess, userLoginFacebookSuccess } from './login.action';
@Injectable()
export class LoginEffects {
loginFacebook$ = createEffect(() => this.actions$.pipe(
ofType(userLoginRequest),
switchMap(() =>
this.authService.loginFacebook()
.pipe(
map((socialUser) => {
this.tokenService.saveToken(socialUser.authToken);
return userLoginFacebookSuccess({socialUser});
})
)
)
)
);
loadUser$ = createEffect(() => this.actions$.pipe(
ofType(userLoginFacebookSuccess),
switchMap((action) =>
this.userService.getUser(action.socialUser)
.pipe(
map((user) => userLoginSuccess({user}))
)
)
)
);
constructor(
private actions$: Actions,
private authService: AuthWrapperService,
private tokenService: TokenStorageService,
private userService: UserService
) {}
}
Login.component.ts
export class LoginComponent implements OnInit {
localUser: IUser;
constructor(
private router: Router,
private store: Store<LoginState>
){}
signInWithFB(): void {
this.store.dispatch(userLoginRequest());
}
ngOnInit() {
this.store.select(selectUser).subscribe( (user) => {
console.log(JSON.stringify(user, undefined, 2));
}
);
}
}
const getLoginState = (state: LoginState) => state;
export const selectUser = createSelector(
getLoginState,
(state: LoginState) => state.user
);
Thank you for assisting me with this!
Best regards,
Tho