Dispatching Actions page
Learn how to dispatch NgRx Actions from within Angular Components.
Quick Start: You can checkout this branch to get your codebase ready to work on this section.
Overview
Update
LoginComponent
to dispatchLoginActions.login
Action.Update
DashboardComponent
to dispatchLoginActions.logout
Action.
Problem 1: Dispatch Login Action on LoginComponent
Now that we have our Actions, let’s use them. The LoginComponent
should have the Login Action be dispatched when the submit button is clicked.
P1: What you need to know
We can import our Action creators from src/app/store/login/login.actions.ts
to create Actions and then use the NgRx Store to dispatch them:
// Note: This example code is not part of our application repo or solution
import { Component } from '@angular/core';
import { Store } from '@ngrx/store';
import * as ContactActions from '../store/contact/contact.actions';
@Component({
selector: 'app-contact',
templateUrl: './contact.component.html',
styleUrls: ['./contact.component.scss'],
})
export class ContactComponent {
constructor(private store: Store) {}
submit(emailAddress: string, fullName: string): void {
this.store.dispatch(ContactActions.submit({ emailAddress, fullName }));
}
}
In upcoming sections, we will discuss how dispatched Actions can trigger Reducer functions (Create a Reducer) and how Effects listen to Actions dispatched from the Store to handle side-effects (Create an API Effect). You can learn more about how to write Actions and how to dispatch them in the NgRx documentation on Actions.
In the LoginComponent
, there is a TODO
where the Login Action should be dispatched.
P1: Solution
src/app/login/login.component.ts
// src/app/login/login.component.ts
import { Component } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';
import { Store } from '@ngrx/store';
import * as LoginActions from '../store/login/login.actions';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss'],
})
export class LoginComponent {
protected readonly form = this.fb.nonNullable.group({
username: ['', [Validators.required]],
password: ['', [Validators.required]],
});
constructor(private fb: FormBuilder, private store: Store) {}
submit(): void {
this.form.markAllAsTouched();
if (this.form.invalid) {
return;
}
this.store.dispatch(
LoginActions.login({
username: this.form.controls.username.value,
password: this.form.controls.password.value,
})
);
}
}
Problem 2: Dispatch Logout Action on DashboardComponent
And the DashboardComponent
should have the Logout Action be dispatched when the logout button is clicked.
P2: What you need to know
In the DashboardComponent
, there is a TODO
where the Logout Action should be dispatched.
P2: Solution
src/app/dashboard/dashboard.component.ts
// src/app/dashboard/dashboard.component.ts
import { Component } from '@angular/core';
import { of } from 'rxjs';
import { Store } from '@ngrx/store';
import * as LoginActions from '../store/login/login.actions';
@Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.scss'],
})
export class DashboardComponent {
// Select username from store
// TODO: Replace `of('TODO')` with selectUsername selector
readonly username$ = of('TODO');
// Select user ID from store
// TODO: Replace `of('TODO')` with selectUserId selector
readonly userId$ = of('TODO');
constructor(private store: Store) {}
logout(): void {
this.store.dispatch(LoginActions.logout());
}
}
Wrap-up: By the end of this section, your code should match this branch. You can also compare the code changes for our solution to this section on GitHub or you can use the following command in your terminal:
git diff origin/dispatch-actions