Another issue is that I had to wrap the filter's arrow function in parens or it would tell me that it couldn't see the routeConfig method. I must have missed something really simple as to why this is not working for me.
import { RouterAction, ROUTER_NAVIGATION, RouterNavigationAction } from '@ngrx/router-store';
import { Actions, Effect } from '@ngrx/effects';
import { Backend } from "./shared/backend";
import { Params, ActivatedRouteSnapshot } from "@angular/router";
import { Store, combineReducers } from "@ngrx/store";
import { Injectable } from "@angular/core";
import { of } from "rxjs/observable/of";
import { Observable } from "rxjs/Observable";
import 'rxjs/add/operator/withLatestFrom';
import 'rxjs/add/operator/switchMap';
//state
export type Forecast = { forecastDate: string, temperatureC: number, temperatureF: number, summary: string };
export type Filters = { date: string };
export type AppState = { filters: Filters, list: number[], forecasts: {[forecastDate:string]:Forecast} };
export type State = { app: AppState }; //this will also contain router state
export const initialState: State = {
app: {
filters: { date: "" },
//user: {},
list: [],
forecasts: {}
}
};
//actions
export type ForecastsUpdated = { type: 'FORECASTS_UPDATED', payload: { forecasts: {[forecastDate:string]: Forecast}, list: number[] }, filters: Filters};
type Action = RouterAction<State> | ForecastsUpdated;
//reducer
export function appReducer(state: AppState, action: Action): AppState
{
switch(action.type)
{
case 'FORECASTS_UPDATED':{
return { ...state, ...action.payload };
}
default:
{
return state;
}
}
}
@Injectable()
export class ForecastsEffects
{
@Effect() navigateToForecasts = this.handleNavigation('forecasts', (r: ActivatedRouteSnapshot) =>
{
const filters = createFilters(r.params);
return this.backend.getForecasts().map(resp => ({ type: 'FORECASTS_UPDATED', payload: { ...resp}}));
});
constructor(private actions: Actions, private store: Store<State>, private backend: Backend, private r: ActivatedRouteSnapshot) { }
private handleNavigation(segment: string, callback: (a: ActivatedRouteSnapshot, state: State) => Observable<any>)
{
const nav = this.actions.ofType(ROUTER_NAVIGATION).map(firstSegment).filter((s => s.routeConfig.path === segment));
return nav.withLatestFrom(this.store).switchMap(a => callback(a[0], a[1]));//.catch(e => {console.log('Network error', e);return of();});
}
}
function firstSegment(r: RouterNavigationAction): ActivatedRouteSnapshot
{
return r.payload.routerState.root.firstChild;
}
function createFilters(p: Params): Filters
{
return { date: p['forecastDate'] || null};
}