You have unlimited access as a PRO member
You are receiving a free preview of 3 lessons
Your free preview as expired - please upgrade to PRO
Contents
Recent Posts
- Object Oriented Programming With TypeScript
- Angular Elements Advanced Techniques
- TypeScript - the Basics
- The Real State of JavaScript 2018
- Cloud Scheduler for Firebase Functions
- Testing Firestore Security Rules With the Emulator
- How to Use Git and Github
- Infinite Virtual Scroll With the Angular CDK
- Build a Group Chat With Firestore
- Async Await Pro Tips
AngularFire2 State Changes With NgRx
Episode 70 written by Jeff DelaneyToday I will show you how to use the stateChanges() method in AngularFire2 to obtain fine-grained control over observable data changes in your NgRx Firebase app.
When and why would I use AngularFire2 StateChanges?
Great question. Imagine you want react differently based on the type of change occurs. For example, you want to flash a green success notification when an item is created, a red danger notification when an item is removed, and a yellow warning notification when an item is modified.
Remind you of anything? That’s exactly how the Firestore web console works, which just so happens to be built with NgRx.
In this demo, I have a collection of pizzas and the restaruant manager wants to keep track of when a pizza is cooking or delivered. We will use NgRx effects to subscribe to stateChanges on a Firestore collection. When a change occurs, our app can react based on whether the object was added
, modified
, and removed
.
Thank you to Booth Group for inspiring me to create this content.
Initial NgRx and AngularFire2 Setup
I am starting with a brand new Angular 5 app, with it’s only dependencies being the NgRx packages and AngularFire2.
If you haven’t already seen my Ngrx Entity Lesson, I highly recommended you go through that first. It will teach you about the entity adapter methods and provide a more in-depth overview of the initial setup.
You must have a Firebase Account and AngularFire2 installed to follow this lesson, please follow the official setup instructions.
Get the full source code for ngrx firestore on Github.
App Module
Make sure you have the necessary NgRx packages installed.
npm install @ngrx/{store,entity,effects,store-devtools} --save |
My final app module looks like this.
@NgModule({ |
Reducers
I am bundling all of my reducers into a /app/reducers/index.ts
. This is not very useful in this tutorial, but it is a good practice as your app grows.
import { ActionReducerMap } from '@ngrx/store'; |
Pizza Feature Module
I highly recommed building feature modules when working with NgRx. Without well-organized features, your app is will quickly spiral out of control.
// pizza.module |
Actions
The action names are very important here. AngularFire2 will provde three different action types in the returned snapshot - added
, modified
, and removed
. Your action string should match exactly, i.e '[Pizza] modified'
. Here are my notes about these actions.
- The initial query will request data from Firestore. You might also add a payload to it modify the query parameters
- After the query, we listen for stateChanges to emit added, modified, or removed.
- The update and success action is used to trigger an update to Firestore,
pizza.actions.ts
import { Action } from '@ngrx/store'; |
Reducer
The reducer contains the pizza interface, as well as the reducer function and entity selectors.
Most of this code is idential to my past NgRx entity lesson, except the reducer function combines the actions from AngularFire2 with the entity methods.
- Adapter - Action
addOne
-added
updateOne
-modified
removeOne
-removed
They work together Mario and Luigi.
pizza.reducer.ts
import * as actions from './pizza.actions'; |
Effects
The stateChanges()
magic happens in the first query effect. It works by mapping the snapshot down to its data, then dispatches a different action based on the type
returned by AngularFire2.
We are also going to take advantage of lettable RxJS operators, which were introduced in v5.5. Ngrx effects code can be nortoriously verbose, but lettable operators help keep your code readable.
pizza.effects.ts
import { Injectable } from '@angular/core'; |
Component
The component is very simple. We run the query during ngOnInit, then provide a button for the user to update the stats.
pizza-order.component.ts
import { Component, OnInit } from '@angular/core'; |
pizza-order.component.html
The HTML is just basic Angular looping and event handling.
<div *ngFor="let pizza of pizzas | async"> |
The End
That’s it for Ngrx Firestore. You now have a reliable way to manage both a local ngrx store and a persistent backend in Firestore.