Reputation: 951
I am testing state management features using ngrx/store like below. The very weird thing is I can't use select method in the user.selectors.ts. It says that Property 'select' does not exist on type 'Observable'. AppState is defined in the reducers.ts properly. To use 'select', import '@ngrx/core/add/operator/select' is added in the user.selectors.ts, also I confirmed that there is select.ts file in the properly located in the node_modules folder.
user.actions.ts
import { Injectable } from '@angular/core';
import { Action } from '@ngrx/store';
@Injectable()
export class UserActions {
static LOGIN = 'LOGIN';
static LOGOUT = 'LOGOUT';
logIn (token: string) {
return { type: UserActions.LOGIN, token };
}
logOut() : Action {
return { type: UserActions.LOGOUT };
}
}
user.reducers.ts
import '@ngrx/core/add/operator/select';
import { Observable } from 'rxjs/Observable';
import { Action } from '@ngrx/store';
import { UserActions } from './user.actions';
export * from './user.actions';
export interface User {
access_token: string;
is_authenticated: boolean;
};
const initialUserState: User = {
access_token: '',
is_authenticated: false
};
export function userReducer(state = initialUserState, action: Action): User {
switch (action.type) {
case UserActions.LOGIN:
return Object.assign( {}, state, { access_token: action.payload })
case UserActions.LOGOUT:
return Object.assign( {}, state, { access_token:'' } )
default:
return state;
}
};
user.selectors.ts
import { Observable } from 'rxjs/Observable';
import { UserProfile } from './user.reducers';
import { AppState } from '../reducers';
import '@ngrx/core/add/operator/select';
export function getUser$(state$: Observable<AppState>): Observable<User> {
return state$.select(state => state.user.access_token);
}
Could you please help me out with this?
The way I build like below.
app - auth
- core - store
- service
- shared
Inside store directory, 5 files are resident, user.actions.ts, user.reducer.ts, user.selectors.ts, app-store.ts and index.ts.
I tried to make one module from store directory like following.
index.ts
import { Observable } from 'rxjs/Observable';
import { NgModule } from '@angular/core';
import { StoreModule, combineReducers } from '@ngrx/store';
import { compose } from '@ngrx/core';
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
import 'rxjs/add/operator/let';
import '@ngrx/core/add/operator/select';
import { UserActions } from './user-profile.actions';
import { userReducer } from './user-profile.reducer';
import { AppState } from './app-store';
@NgModule({
imports: [
StoreModule.provideStore({userReducer}),
],
declarations: [],
exports: [],
providers: [UserActions]
})
export class CoreStoreModule {};
FYI, app-store.ts looks like below.
import { User } from './user.reducer';
export interface AppState {
user: User;
};
Upvotes: 1
Views: 1736
Reputation: 9331
Seeing your syntax, it looks like you are using older ngrx ( version 2 ) . The newer (version 4) is little different. I will give syntax for the older version here as you are already using it .
Your action code is correct, just remove @Injectable
we are not injecting it anywhere. Reducer also seems fine.
If you want to access in your user service the code needs to be this way:
import { Store } from '@ngrx/store';
@Injectable()
public class UserService{
constructor(private store: Store<any>){}
public getUser(): Observable<User>{
return this.store.select('userReducer');
}
}
This is not the best way , but if you get something working, you can improve it further.
In your component you can say
constructor(private userService: UserService){
this.userService.getUser().subscribe((user: User)=> console.log(user));
}
Upvotes: 2