Discover how to make your app react perfectly to changes without messy code!
Why Effect for side effects in Angular? - Purpose & Use Cases
Start learning this pattern below
Jump into concepts and practice - no test required
Imagine you want to run some code whenever a user clicks a button or when some data changes, like logging a message or fetching new information.
You try to do this by manually watching for changes and calling functions everywhere in your code.
Manually tracking when to run side actions is tricky and easy to forget.
You might run the code too many times or miss running it at all, causing bugs and confusing behavior.
Angular's Effect lets you declare side effects clearly and automatically runs them when needed.
This keeps your code clean and reliable, so side actions happen exactly when they should.
button.addEventListener('click', () => { console.log('Clicked!'); fetchData(); });
effect(() => { if (signal()) { console.log('Clicked!'); fetchData(); } });You can easily run side actions tied to state changes without messy manual checks.
When a user toggles a switch, you want to save their preference and update the UI smoothly without extra event wiring.
Manual side effect handling is error-prone and hard to maintain.
Effect provides a clear, automatic way to run side actions in Angular.
This leads to cleaner code and better app behavior.
Practice
Effect in Angular?Solution
Step 1: Understand what side effects mean in Angular
Side effects are extra tasks like fetching data or logging that happen outside the main app logic.Step 2: Identify the role of Effects
Effects run these side tasks automatically when app state changes, keeping main logic clean.Final Answer:
To run side tasks like data loading or logging when app state changes -> Option DQuick Check:
Effect = side tasks on state change [OK]
- Thinking Effects handle UI layout
- Confusing Effects with event handlers
- Believing Effects style components
Solution
Step 1: Recall the correct RxJS operators for Effects
Effects usepipewith operators likeofTypeto filter actions andtapfor side effects.Step 2: Check each option's syntax
createEffect(() => this.actions$.pipe(ofType(loadData), tap(() => console.log('Loading')))) correctly usespipe,ofType, andtap. Others misuse operators or subscribe directly, which is incorrect inside Effects.Final Answer:
createEffect(() => this.actions$.pipe(ofType(loadData), tap(() => console.log('Loading')))) -> Option CQuick Check:
Effect uses pipe + ofType + tap [OK]
- Using subscribe inside createEffect
- Using map instead of tap for side effects
- Using filter without ofType
loadData$ = createEffect(() => this.actions$.pipe(
ofType('LOAD_DATA'),
tap(() => console.log('Data loading started'))
), { dispatch: false });What will happen when the 'LOAD_DATA' action is dispatched?
Solution
Step 1: Understand the effect's dispatch option
Settingdispatch: falsemeans this Effect does not send out new actions after running.Step 2: Analyze the tap operator
Thetapoperator runs side code like logging but does not change or dispatch actions.Final Answer:
The message 'Data loading started' is logged, and no new action is dispatched -> Option AQuick Check:
dispatch false means no new action, tap logs side effect [OK]
- Assuming tap dispatches actions
- Thinking dispatch: false disables effect
- Confusing tap with map or switchMap
saveData$ = createEffect(() => this.actions$.pipe(
ofType('SAVE_DATA'),
map(() => this.api.save()),
tap(() => console.log('Save triggered'))
));Solution
Step 1: Check the map operator usage
map must return a new action object for dispatching, butthis.api.save()likely returns a Promise or void, not an action.Step 2: Understand effect dispatch requirements
Effects expect actions to be returned for dispatch unlessdispatch: falseis set, which is missing here.Final Answer:
Using map without returning an action causes an error -> Option AQuick Check:
map must return action for dispatch [OK]
- Ignoring missing action return in map
- Thinking tap cannot follow map
- Confusing ofType with filter
Solution
Step 1: Identify async handling with switchMap
UsingswitchMapallows calling the async login API and switching to its result stream.Step 2: Handle success and error properly
Inside switchMap,mapcreates a success action, andcatchErrorreturns a failure action wrapped inofto keep the stream alive.Final Answer:
login$ = createEffect(() => this.actions$.pipe( ofType('LOGIN'), switchMap(action => this.authService.login(action.credentials).pipe( map(user => ({ type: 'LOGIN_SUCCESS', user })), catchError(() => of({ type: 'LOGIN_FAILURE' })) )) )); -> Option BQuick Check:
Use switchMap + map + catchError for async effects [OK]
- Using tap instead of switchMap for async calls
- Not handling errors with catchError
- Returning promises instead of observables
