I use NgRx recently with effects to manage send API requests. My API requests are in a service and my effect uses this service. Very classic.
@Injectable({
providedIn: 'root'
})
export class MaterialService {
private url = "materials";
constructor(private http: HttpClient) { }
getMaterials () {
return this.http.get (this.url).pipe (
catchError (this.handleError)
);
}
handleError (error: HttpErrorResponse): Observable<never> {
return throwError (error.message);
}
}
@Injectable()
export class MaterialEffects {
@Effect() loadMaterial$ = this.dataPersistence.fetch(
MaterialActionTypes.LoadMaterial,
{
run: (action: LoadMaterial, state: MaterialPartialState) => {
return this.materialService.getMaterials ().pipe (
map (data => {
return new MaterialLoaded(data);
}),
// catchError (error => of (new MaterialLoadError (error)))
);
},
onError: (action: LoadMaterial, error) => {
console.error('Error', error);
return new MaterialLoadError(error);
}
}
);
...
Overall it works great. I just love it :)
But for certain requests, I need to recover some ID to create my URL. These IDs are mostly generic IDs. For example the ID of our client.
https://my.example.com/perimeters/[PERIMETER_ID]/relationships/users
How can I use my service to retrieve my content ID from my store, create my URL and return my Observable as expected?
thank you in advance
Inject the store into your effects class MaterialEffects
, and get the value you need, then pass that as a parameter into your MaterialService
.
So your effect would look like:
@Injectable()
export class MaterialEffects {
constructor(private store: Store<any>)
@Effect() loadMaterial$ = this.dataPersistence.fetch(
MaterialActionTypes.LoadMaterial,
{
run: (action: LoadMaterial, state: MaterialPartialState) => {
return this.store.pipe(
select(x => x.perimiterId),
mergeMap((perimiterId) => {
materialService.getMaterials(perimiterId).pipe(
map(data => {
return new MaterialLoaded(data);
}),
// catchError (error => of (new MaterialLoadError (error)))
)
})
)
},
onError: (action: LoadMaterial, error) => {
console.error('Error', error);
return new MaterialLoadError(error);
}
}
);
...