angular reactive extensions and it's state management solution for the angular
NGRX is a popular state management library specifically designed for Angular.
NgRx uses concepts such as actions, reducers, effects, and selectors to manipulate the state in a controlled manner.
The store can be seen as your client side database. it reflects the state of your application. You can see it as the single source of truth. The application state is maintained in the store. It is immutable. The data contained therein cannot be changed directly. Therefore, all state changes must be done through actions. These actions define what will be changed in the state through a mechanism called the "reducer"
Reducers are responsible for handling the transition from one state to another. Reducers are pure functions that specify how the application’s state changes in response to actions. They take the current state and an action as input and return a new state. Pure means that the function always returns the same value for the same input and that it has no side effects
Actions modify the state of the store by using reducers. Actions are plain JavaScript objects that describe state changes. They are dispatched to the store and trigger reducers. Actions are the payload that contains needed information to alter your store. Basically, an action has a type and a payload that your reducer function will take to alter the state.
Selectors are pure functions used to extract specific pieces of data from the store. The "selectors" are functions used to access and get specific information of state stored
Effects are used to interact with services, perform HTTP requests, and dispatch new actions based on the results. This ensures that side effects are isolated and handled separately from the main application state.
The "effects" refer to functionalities that deal with asynchronous tasks or side effects, such as network requests, database access, calls to external APIs, or any operation that is not purely synchronous.
an action is a plain JavaScript object that we send to the store in order to trigger some modification action is just a plain JavaScript payload containing some data and a type. The type tells to the store what to do with the action depending on the type the store is going to call each action has a type, which is a string. Each action also contains a payload. action will be call using disptach for triger actions
```js
export const login = createAction(
"[Login Page] User Login",
props<{user: User}>()
);
```
```js
this.store.dispatch(AuthActions.login({user}));
```
reduce functional programming operation. the name rroducer comes from the reduced functional programming operation. a reducer function. The user function. It's a plain JavaScript function that. It's a new version of the state, so in this case, our authentication reducer to the previous value
export interface AuthState {
user: User
}
export const initialAuthState: AuthState = {
user: undefined
};
export const authReducer = createReducer(
initialAuthState,
on(AuthActions.login, (state, action) => {
return {
user: action.user
}
}),
);
moudle.ts
StoreModule.forFeature('auth', authReducer),
Selector is simply a plain mapping function with memory. We use these mapping functions to query our star state and get back the values that the view needs to
```js
export const selectAuthState =
createFeatureSelector<AuthState>("auth");
export const isLoggedIn = createSelector(
selectAuthState,
auth => !!auth.user
);
export const isLoggedOut = createSelector(
isLoggedIn,
loggedIn => !loggedIn
);
```
### EFFECTS
effect rovides a way to isolate side effects into its model, outside the NgRx store and the Angular components. we can use the ofType operator. This acts as a filter, and will only invoke the Effect when it receives the configured action(s)
all states are at the frontend, but in a real app, it needs to call backend DB or MQ, etc, these calls have side effects. The framework used to factor out these effects into a common place.
Effects are used to handle network requests, web socket messages and time-based events. Effects are useful for fetching data and long-running tasks.
In our Angular application, generally our components interact directly to services. It is better to isolate them using Effect.
Effects perform synchronous or asynchronous tasks and return new Action.
@Injectable()
export class AuthEffects {
login$ = createEffect(() =>
this.actions$
.pipe(
ofType(AuthActions.login),
tap(action => localStorage.setItem('user',
JSON.stringify(action.user))
)
)
,
{dispatch: false});
```
```js
module.ts
EffectsModule.forFeature([AuthEffects])
```
https://itnext.io/ngrx-complete-guide-with-angular-learn-by-doing-simple-crud-operations-95d1414e765d