Jump into concepts and practice - no test required
or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Using Effect for Side Effects in Angular Signals
📖 Scenario: You are building a simple Angular standalone component that tracks a user's name and shows a greeting message. You want to log a message to the console every time the user's name changes, using Angular's effect function for side effects.
🎯 Goal: Create an Angular standalone component that uses a signal to store the user's name and an effect to log a message to the console whenever the name changes.
📋 What You'll Learn
Create a signal called userName with the initial value '' (empty string).
Create a signal called greeting that returns `Hello, ${userName()}`.
Use Angular's effect function to log `User name changed to: ${userName()}` whenever userName changes.
Create a standalone Angular component named UserGreetingComponent with a template that includes an input bound to userName and displays the greeting.
💡 Why This Matters
🌍 Real World
Using Angular signals and effects helps build reactive user interfaces that respond to user input and other changes efficiently.
💼 Career
Understanding Angular signals and effects is important for modern Angular development, especially for building clean, reactive components with side effects like logging or API calls.
Progress0 / 4 steps
1
Create the userName signal
Create a signal called userName with the initial value '' (empty string) inside the UserGreetingComponent.
Angular
Hint
Use signal('') to create a signal with an empty string.
2
Create the greeting signal
Inside UserGreetingComponent, create a signal called greeting that returns the string `Hello, ${userName()}` using an arrow function.
Angular
Hint
Use computed(() => `Hello, ${this.userName()}`) to create a computed signal.
3
Add an effect to log changes
Import effect from @angular/core and inside UserGreetingComponent create an effect that logs `User name changed to: ${userName()}` whenever userName changes.
Angular
Hint
Use effect(() => { ... }) inside the constructor to watch userName.
4
Add template with input and greeting display
Add a template to UserGreetingComponent with an <input> element bound to userName using [ngModel] and (ngModelChange), and a <p> element that displays the greeting() signal.
Angular
Hint
Use [ngModel]="userName()" and (ngModelChange)="userName.set($event)" on the input, and display {{ greeting() }} in a paragraph.
Practice
(1/5)
1. What is the main purpose of an Effect in Angular?
easy
A. To style components with CSS dynamically
B. To define the main UI layout of a component
C. To handle user input events directly in the template
D. To run side tasks like data loading or logging when app state changes
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 D
Quick Check:
Effect = side tasks on state change [OK]
Hint: Effects run extra tasks when app data changes [OK]
Common Mistakes:
Thinking Effects handle UI layout
Confusing Effects with event handlers
Believing Effects style components
2. Which of the following is the correct way to create an Effect in Angular using RxJS operators?
easy
A. createEffect(() => this.actions$.subscribe(action => console.log(action)))
B. createEffect(() => this.actions$.map(action => action.type))
C. createEffect(() => this.actions$.pipe(ofType(loadData), tap(() => console.log('Loading'))))
D. createEffect(() => this.actions$.filter(action => action.type === 'loadData'))
Solution
Step 1: Recall the correct RxJS operators for Effects
Effects use pipe with operators like ofType to filter actions and tap for side effects.
Step 2: Check each option's syntax
createEffect(() => this.actions$.pipe(ofType(loadData), tap(() => console.log('Loading')))) correctly uses pipe, ofType, and tap. Others misuse operators or subscribe directly, which is incorrect inside Effects.
Final Answer:
createEffect(() => this.actions$.pipe(ofType(loadData), tap(() => console.log('Loading')))) -> Option C
Quick Check:
Effect uses pipe + ofType + tap [OK]
Hint: Use pipe with ofType and tap inside createEffect [OK]
A. Using map without returning an action causes an error
B. tap cannot be used after map
C. ofType should be replaced with filter
D. createEffect must not use arrow functions
Solution
Step 1: Check the map operator usage
map must return a new action object for dispatching, but this.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 unless dispatch: false is set, which is missing here.
Final Answer:
Using map without returning an action causes an error -> Option A
Quick Check:
map must return action for dispatch [OK]
Hint: map must return an action unless dispatch: false [OK]
Common Mistakes:
Ignoring missing action return in map
Thinking tap cannot follow map
Confusing ofType with filter
5. You want to create an Effect that listens for a 'LOGIN' action, calls an async login API, and then dispatches either 'LOGIN_SUCCESS' or 'LOGIN_FAILURE' based on the result. Which code snippet correctly implements this?