I have an application that has state classes for a number of topic areas in the application. Say it is a chat app and the the topics are users, chat messages and chat rooms. The user is authenticated/authorized by logging in. From there after the state is depends on the user that is logged in. When the user logs out, the app needs to reset the state of all of the 'topics' to their default state.
Questions:
Each feature module should define its own slice of state in a pair of files named feature-name.actions.ts
and feature-name.state.ts
, located inside the feature subdirectory (see the official style guide).
As you said, each feature state can respond to actions defined in other states, and update its own state accordingly. Here's an example:
src/app/auth/auth.state.ts:
...
// Import our own actions, including the Logout action
import { Logout, ... } from './auth.actions';
export interface AuthStateModel {
token?: string;
currentUser?: User;
permissions: string[];
}
const defaults: AuthStateModel = {
token : null,
currentUser: null,
permissions: [],
};
@State<AuthStateModel>({
name: 'auth',
defaults
})
export class AuthState {
...
// Respond to the Logout action from our own state
@Action(Logout)
logout(context: StateContext<AuthStateModel>) {
context.setState({ ...defaults });
}
...
}
src/app/users/users.state.ts:
...
// Import our own actions
import { LoadAllUsers, ... } from './users.actions';
// Import the Logout action from the Auth module
import { Logout } from '../auth/auth.actions';
export interface UsersStateModel {
users?: User[];
}
const defaults: UsersStateModel = {
users: null,
};
@State<UsersStateModel>({
name: 'users',
defaults
})
export class UsersState {
...
// An example of the usual case, responding to an action defined in
// our own feature state
@Action(LoadAllUsers)
loadUsers(context: StateContext<UsersStateModel>, action: LoadAllUsers) {
...
}
// Respond to the Logout action from the Auth state and reset our state (note
// that our context is still of type StateContext<UsersStateModel>, like the other
// actions in this file
@Action(Logout)
logout(context: StateContext<UsersStateModel>) {
context.setState({ ...defaults });
}
...
}
Note that although AuthState.logout()
and UsersState.logout()
both respond to the Logout
action (defined in the AuthState module), the AuthState.logout()
function accepts a context of type StateContext<AuthStateModel>
, because we want to call that context's setState()
function to update the 'auth' feature state. However, the UsersState.logout()
function accepts a context of type StateContext<UsersStateModel>
, because we want to call that context's setState()
function to reset the 'users' feature state.
Each additional feature module can respond to the Logout action in the same way as UsersState did, and reset their own slice of the state.