1
votes

I'm facing NgRx and I can't understand how could be so hard add a value to the store and retrieve it. Anyway, that's what I have done so far

Effects ts:

export class idEffects {

    saveId$ = createEffect(() =>
    this.actions$
        .pipe(
            ofType(idActions.addIdAction),
            tap(payload => {
                console.log("action",payload);
            })
        )
    ,{dispatch: false});

    constructor(
      private actions$: Actions
    ) {}
  }

Actions ts:

export const ADD_ID = '[Id Action] add id';

export const addIdAction = createAction(
    ADD_ID,
    props<{id: any}>()
)

Reducer ts:

export interface IdState {
    id: any;
}

export const defaultId: IdState = {
    id: undefined
};

export const idReducer = createReducer (
    defaultId,

    on(idActions.addIdAction, (state, action) => {
        //console.log("Calling id reducer", action);
        return {
            id: action
        }
    })
)

and the Selector ts:

export const selectIdState = 
createFeatureSelector<IdState>("id")

export const selectIdValue = createSelector(
    selectIdState,
    id => id
);

Now, that's what I have in my app.module.ts

StoreModule.forRoot({id: idReducer}),
    EffectsModule.forRoot([IdEffects]),
    StoreModule.forRoot(reducers, {
      metaReducers
    }),
    StoreDevtoolsModule.instrument({maxAge: 25}),
    StoreRouterConnectingModule.forRoot({
      stateKey: 'router',
      routerState: RouterState.Minimal
    })

It seems that the storing data is working well because the Redux panel in my console return this:

id(pin):"1"
data(pin):"Hello There"
type(pin):"[Id Action] add id"

But, when I try to retrieve this object I get an undefined and I do it in this way:

this.id$ = storeId.pipe(select(selectIdValue))

and in the html

<h4>The id obj is: {{id$ | async}}</h4>

But it doesn't write anything. I tried to get the result using a subscribe in the component, and it gets me undefined how could be possibile?

1

1 Answers

1
votes

the state is

export interface IdState {
    id: any;
}

therefore selector should select id from its feature state

export const selectIdValue = createSelector(
    selectIdState,
    state => state.id, // selectIdState returns an object of IdState interface.
);

then, the reducer, it should add the id prop to the state, not an action

    on(idActions.addIdAction, (state, action) => {
        //console.log("Calling id reducer", action);
        return {
            ...state, // not needed in your case, but a good style.
            id: action.id, // <- .id
        }
    }),

the effect, it's not needed and you can remove it.

and the last thing the reducers variable. Could you share its source? It should be

const reducers = {
  id: idReducer, // id key is important, idReducer is enough for now.
};

and don't forget to dispatch somewhere addIdAction. for example in ngOnInit of a component.

this.store.dispatch(addIdAction({id: 'value'}));

If you have things like that - it should work. Let me know if you have more questions.