Search code examples
angulartypescriptobservablengrxrxjs6

Grouping and reducing a custom observable array which was received from ngrx state tree


I receive my data from an API call. The data is received via ngrx-effects and passed into the state tree. Then I'm able to fetch the data in my angular component's constructor and do some rxjs operations like mergeMap and reduce to convert it to a format that I need to display the data in UI.

I tried replicate the scenario in stackblitz and it's working as expected. Please find the link below

link: https://stackblitz.com/edit/typescript-rxjs-reduce

workflow state tree:

export interface WorkflowsState {
    workflows : workflow[] | [],
    allWorkflowsLoaded : false
}

Overall App State tree:

interface Appstate {
    workflows: WorkflowsState,
    smartNav: SmartNavState
}

Effect method:

@Effect() loadWorkflows$ = this.actions$.pipe(
    ofType(WorkflowsActionTypes.LoadWorkflows),
    switchMap((action: LoadWorkflows) =>
    this.http.get(url)
    .pipe(map((res: Workflow[]) => new WorkflowsLoaded(res))))
);

Reducer section:

switch (action.type) {
    case: WorkflowsActionTypes.WorkflowsLoaded:
    return {
        allWorkflowsLoaded : true,
        workflows: action.payload
};

public variables declared in dashboard component:

public workflows$ : Observable<workflow[]>;
public dashboardTile$ : Observable<dashboardTile[]>;

constructor with selector:

constructor(private store : Store<AppState>) {
    this.workflows$ = this.store.select(state => state.workflows.workflows);
}

Not sure about why it's not working when the data is fetched from API. I require the same output as displayed in the sample's (stackblitz link) console section. I'm able to get the data from api but dashboardTile$ is returning as null.


Solution

  • After 2 hours of struggle found out the issue lies with the usage of reduce operator instead of the scan operator. Since the ngrx state object is not yet complete it was not returning the accumulated array. Once is replaced reduce operator with scan, it started giving me the desired output. The following post helped me in identifying the fix.

    Reduce returns empty array, however scan does not