What is one of the harder things, if not the hardest, you have ever done in an Angular project?
State
State
Angular State Management - Start Local
@devupconf - STL 2022
Chau Tran
twitter.com/@nartc1410
github.com/nartc
and all the Sponsors (https://www.devupconf.org/sponsors)
and all the Sponsors (https://www.devupconf.org/sponsors)
When should we use state management?
– Any Angular developer ever
There should be 3 answers here
Never
Never
Never
Never
When needed or "it depends"
Never
Never
When needed or "it depends"
Always
Never
Never
When needed or "it depends"
Always
Subject as a Service
Never
Never
When needed or "it depends"
Always
Never
Never
When needed or "it depends"
Always
❌
Never
Never
When needed or "it depends"
Always
✅
and more.
(who doesn't like to own a State Management library)
Common?
Global State Management
What is State Management?
What is State Management?
FeatureA
FeatureB
FeatureC
StateA
StateB
StateC
App
FeatureA
FeatureB
FeatureC
StateA
StateB
StateC
App
FeatureA
FeatureB
FeatureC
StateA
StateB
StateC
App
FeatureA
FeatureB
FeatureC
StateA
StateB
StateC
App
Primer on
Local Component State
Primer on
Local Component State
Primer on
Local Component State
Anything that contributes to rendering a component
Primer on
Local Component State
Anything that contributes to rendering a component
Persisted State
Primer on
Local Component State
Anything that contributes to rendering a component
Persisted State
URL State
Primer on
Local Component State
Anything that contributes to rendering a component
Persisted State
URL State
Client State
Primer on
Local Component State
Anything that contributes to rendering a component
Persisted State
URL State
Client State
Local UI State
Primer on
Local Component State
Anything that contributes to rendering a component
Persisted State
URL State
Client State
Local UI State
Primer on
Local Component State
Anything that contributes to rendering a component
Persisted State
URL State
Client State
Local UI State
What do we even want from a State Management solution?
In my opinion, a State Management solution should provide
In my opinion, a State Management solution should provide
- Ability to read states with some diffing mechanism
In my opinion, a State Management solution should provide
- Ability to read states with some diffing mechanism
- Ability to write to states fully or partially
In my opinion, a State Management solution should provide
- Ability to read states with some diffing mechanism
- Ability to write to states fully or partially
- Ability to handle side-effects
In my opinion, a State Management solution should provide
- Ability to read states with some diffing mechanism
- Ability to write to states fully or partially
- Ability to handle side-effects
- Ease of clean up
In my opinion, a State Management solution should provide
- Ability to read states with some diffing mechanism
- Ability to write to states fully or partially
- Ability to handle side-effects
- Ease of clean up
@Injectable()
export class StateService {
private state$ = new ReplaySubject(1);
}
In my opinion, a State Management solution should provide
- Ability to read states with some diffing mechanism
- Ability to write to states fully or partially
- Ability to handle side-effects
- Ease of clean up
@Injectable({ providedIn: 'root' })
export class StateService {
private state$ = new ReplaySubject(1);
}
In my opinion, a State Management solution should provide
- Ability to read states with some diffing mechanism
- Ability to write to states fully or partially
- Ability to handle side-effects
- Ease of clean up
@Injectable()
export class StateService {
private state$ = new ReplaySubject(1);
}
In my opinion, a State Management solution should provide
- Ability to read states with some diffing mechanism
- Ability to write to states fully or partially
- Ability to handle side-effects
- Ease of clean up
@Injectable()
export class StateService {
private state$ = new ReplaySubject(1);
select(selector) {
return this.state$.pipe(
map(state => selector(state)),
distinctUntilChanged()
)
}
}
In my opinion, a State Management solution should provide
- Ability to read states with some diffing mechanism
- Ability to write to states fully or partially
- Ability to handle side-effects
- Ease of clean up
@Injectable()
export class StateService {
private state$ = new ReplaySubject(1);
select(selector) {
return this.state$.pipe(
map(state => selector(state)),
distinctUntilChanged()
)
}
setState(state) {
if (typeof state === 'function') {
this.state$.next(state(this.state$.getValue()));
} else {
this.state$.next(state);
}
}
patchState(partialState) {
const currentState = this.state$.getValue();
if (typeof partialState === 'function') {
this.state$.next({
...currentState,
...partialState(currentState)
});
} else {
this.state$.next({
...currentState,
...partialState
})
}
}
}
In my opinion, a State Management solution should provide
- Ability to read states with some diffing mechanism
- Ability to write to states fully or partially
- Ability to handle side-effects
- Ease of clean up
@Injectable()
export class StateService {
private state$ = new ReplaySubject(1);
select(selector) {
return this.state$.pipe(
map(state => selector(state)),
distinctUntilChanged()
)
}
setState(state) {
// ...
}
patchState(partialState) {
// ...
}
effect(trigger) {
return trigger.subscribe();
}
}
In my opinion, a State Management solution should provide
- Ability to read states with some diffing mechanism
- Ability to write to states fully or partially
- Ability to handle side-effects
- Ease of clean up
@Injectable()
export class StateService {
private state$ = new ReplaySubject(1);
private destroy$ = new ReplaySubject(1);
select(selector) {
return this.state$.pipe(
map(state => selector(state)),
distinctUntilChanged()
)
}
setState(state) {
// ...
}
patchState(partialState) {
// ...
}
effect(trigger) {
return trigger
.pipe(takeUntil(this.destroy$))
.subscribe();
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
}
@Injectable()
export class StateService {
private state$ = new ReplaySubject(1);
private destroy$ = new ReplaySubject(1);
select(selector) {
return this.state$.pipe(
map(state => selector(state)),
distinctUntilChanged()
)
}
setState(state) {
// ...
}
patchState(partialState) {
// ...
}
effect(trigger) {
return trigger
.pipe(takeUntil(this.destroy$))
.subscribe();
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
}
Congratulations!
You just implemented
@ngrx/component-store
Pull-based state management
@ngrx/component-store
@ngrx/component-store
@ngrx/component-store
Read
Write
Side-effect
@ngrx/component-store
Read
Write
Side-effect
@ngrx/store
@ngrx/component-store
Read
Write
Side-effect
@ngrx/store
createSelector()
createReducer()
createEffect()
@ngrx/component-store
Read
Write
Side-effect
@ngrx/store
createSelector()
createReducer()
createEffect()
@ngrx/component-store
select()
setState()
effect()
Demo
Credits
Laura - https://twitter.com/ltciro
Diana - https://twitter.com/dicaro87
Thank you
Angular - Start Local
By Chau Tran
Angular - Start Local
We have experienced a revolution in the Front-End with innovative ideas from Frameworks and libraries, however, how can our Back-End learn and benefit from this?, The architecture in Node can be a headache, Do not lose your mind!. Let's increase our technical skills and level of happiness, building robust applications in a simple, consistent and fast way, without losing the simplicity of Node with Nest.js; a framework based on the Angular design that provides the best concepts for scalable systems. Additionally, Nest.js is a short route for the approach of Angular developers to Node.js
- 410