Use your State! Leverage the power of facades
Now that you have set up state for an entity, it is time to start using it. With NgRx Auto-Entity, if you leverage our pre-fabricated facades, we have made using state about as easy as it can get. Start by creating a facade class that derives from the facade base class generated by your call to buildState
:
facades/customer.facade.ts
Copy import { Injectable } from '@angular/core' ;
import { Store } from '@ngrx/store' ;
import { AppState } from 'state/app.state' ;
import { CustomerFacadeBase } from '../state/customer.state' ;
import { Customer } from '../models' ;
@ Injectable ({ providedIn : 'root' })
export class CustomerFacade extends CustomerFacadeBase {
constructor (store : Store < AppState >) {
super (Customer , store);
}
// TODO: Extend your facade's functionality here!
}
With your facade in hand, inject it into your component and use the facade to interact with your entities:
components/customer.component.ts components/customer.component.html
Copy import { ActivatedRoute } from '@angular/router' ;
// ... other imports ...
import { CustomerFacade } from '../facades' ;
import { Customer } from '../models' ;
@ Component ({
selector : 'app-customer' ,
templateUrl : './customer.component.html' ,
styleUrls : [ './customer.component.scss' ]
})
export class CustomerComponent implements OnInit {
customer$ : Observable < Customer >;
constructor (
private activatedRoute : ActivatedRoute ,
private customerFacade : CustomerFacade // No store, no selectors!
) {}
ngOnInit () {
this .customer$ = this . activatedRoute . paramMap .pipe (
filter (params => params .has ( 'id' )) ,
map (params => + params .get ( 'id' )) ,
tap (id => {
this . customerFacade .selectByKey (id); // Facades FTW!
this .hasCustomer (id)
.pipe ( first ())
.subscribe (exists => {
if ( ! exists) {
this . customerFacade .load (id); // Facades FTW!
}
});
}) ,
switchMap (() => this . customerFacade .current$) // Facades FTW!
);
}
hasCustomer (id : number ) : Observable < boolean > {
return this . customerFacade . ids$ .pipe ( // Facades FTW!
map ((ids : number []) => ids .indexOf (id) > - 1 )
);
}
onSave (customer : Customer ) : void {
if ( customer .id == null ) {
this . customerFacade .create (customer); // Facades FTW!
} else {
this . customerFacade .update (customer); // Facades FTW!
}
}
}
Copy <div class="customers">
<div>
<h2>Customer</h2>
<app-customer-form
#customerForm
[customer]="customer$ | async"
(saved)="onSave($event)">
</app-customer-form>
<div>
<button routerLink="/customers">Cancel</button>
<button (click)="customerForm.save()" [disabled]="!customerForm.valid">
Save
</button>
</div>
</div>
</div>
Note the changes here. We imported only the activated route and a facade into our component. Our component does not import any state-related types at all. No actions, no store, no app state interface, none of the usual suspects. All state interactions occur through the facade.