When onMetaSignalChanged() is called in the component, it causes an effect which in turn calls the reducer case rangeSchemasLoadCompletedSuccess. I have debugged the App and its working fine till that point. As you can see rangeSchemasLoadCompletedSuccess updating the rangeSchemas of store state, so I think my rangeSchemas$ observable should get the updated value after that? But its not being updated, Am I missing something?
Model Class:
export interface RangeSchemaViewModel {
id: number;
rangeSchemaName: string;
}
In my component I'm selecting the store state as:
export class MyComponent implements OnInit, OnDestroy {
rangeSchemas$: Observable<RangeSchemaViewModel[]>;
ngOnInit() {
this.rangeSchemas$ = this.store.pipe(
select(RawSignalsStoreSelectors.selectRangeSchemasViewModel)
);
}
onMetaSignalChanged(event: any) {
this.store.dispatch(
RawSignalsStoreActions.changeMetaSignal({ id: event.meta_Signal_Id })
);
}
//onmetaSignalChanged, Action is called which is updating the state of rangeSchemas$
}
Here is my selector code:
const getRangeSchemas = (state: State): RangeSchema[] => state.rangeSchemas;
export const selectRangeSchemasState: MemoizedSelector<
object,
State
> = createFeatureSelector<State>('raw-signals');
export const selectRangeSchemasViewModel: MemoizedSelector<
object,
RangeSchemaViewModel[]
> = createSelector(
selectRangeSchemasState,
getRangeSchemas,
(state, rangeSchemas) => {
return rangeSchemas.map((item) =>{
let rangeSchemaViewModel: RangeSchemaViewModel;
rangeSchemaViewModel.id= item.mapping.id;
rangeSchemaViewModel.rangeSchemaName= item.mapping.rangeSchemaName;
return rangeSchemaViewModel;
})
});
Reducer Code:
on(rawSignalsActions.changeMetaSignal, (state, { id }) => ({
...state,
linkedMetaSignal: state.metaSignals.filter(item => item.id === id)[0]
})),
on(rawSignalsActions.rangeSchemasLoadCompletedError, state => ({
...state,
loading: { ...state.loading, rangeSchemas: false }
})),
on(rawSignalsActions.rangeSchemasLoadCompletedSuccess,
// tslint:disable-next-line: no-shadowed-variable
(state, { rangeSchemas }) => ({
...state,
rangeSchemas,
loading: { ...state.loading, rangeSchemas: false }
})
)
Effects Code:
getRangeSchemas$ = createEffect(() =>
this.actions$.pipe(
ofType(RawSignalsActions.changeMetaSignal),
concatMap(action => this.rawSignalsDataService.getRangeSchemas(action.id).pipe(
map(rs1 => this.constructSignalCounts(rs1)),
map(rs2 => RawSignalsActions.rangeSchemasLoadCompletedSuccess( { rangeSchemas: rs2 })),
catchError(err => of(RawSignalsActions.rangeSchemasLoadCompletedError({ error: err })))
)),
));
constructSignalCounts = ( rangeSchemas: RangeSchema[]) => {
for (var rangeSchema of rangeSchemas){
let signalCounts: SignalCount[] = [];
for (var abstractSignal of rangeSchema.abstractSignals) {
let signalCount: SignalCount = { range: "0", populationSize: 0, populationPerc: 0, lowRange: 0, highRange:0 };
signalCount.range = abstractSignal.abstractSignal.name;
signalCount.populationSize = 20;
signalCount.populationPerc = 40;
if (rangeSchema.mapping.type == 2) { // 2 -> numeric, 3 -> Text
// actually type will come from Signal Range Schema
signalCount.lowRange = abstractSignal.numericMappings[0].minValue;
signalCount.highRange = abstractSignal.numericMappings[0].maxValue;
}
signalCounts.push(signalCount);
}
rangeSchema.signalCounts = signalCounts;
}
return rangeSchemas;
};
After a struggle of almost 2 days I found the answer! Here is the selector code which fixed the issue:
export const selectRangeSchemasState: MemoizedSelector<
object,
State
> = createFeatureSelector<State>('raw-signals');
const getRangeSchemas = (state: State): RangeSchema[] => state.rangeSchemas;
export const selectRangeSchemasViewModel: MemoizedSelector<
object,
RangeSchemaViewModel[]
> = createSelector(
selectRangeSchemasState,
getRangeSchemas,
(state, rangeSchemas) => {
return state.rangeSchemas.map(item => {
let rangeSchemaViewModel: RangeSchemaViewModel = {
id: 0,
rangeSchemaName: ''
};
rangeSchemaViewModel.id = item.mapping.id;
rangeSchemaViewModel.rangeSchemaName = item.mapping.rangeSchemaName;
return rangeSchemaViewModel;
});
}
);
The reasons of problem are following:
Its the global state from which I should construct the view Model i.e.,
return state.rangeSchemas.map(item => {...
rangeSchemaViewModel variable was undefined so I instantiated it with default values.
let rangeSchemaViewModel: RangeSchemaViewModel = {
id: 0,
rangeSchemaName: ''
};