Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ngrx/store selector returns function instead of object

I am following the example-app (https://github.com/ngrx/example-app), all my stores, effects, actions are working great but I am getting weird behaviour when using selector defined in the reducer file vs selector defined in the container file. The selector defined in the reducer file returns the function whereas the selector defined in the container file returns the object. I have copied code snippet to explain this in details. I would like to define the shared selector hence it is easy to maintain and upgrade easily instead of defining in the container component every time. I appreciate if someone shed some light to resolve this issue.

//package.json

{
    dependencies: {
        "@angular/common": "2.2.1",
        "@angular/compiler": "2.2.1",
        "@angular/compiler-cli": "2.2.1",
        "@angular/core": "2.2.1",
        "@angular/forms": "2.2.1",
        "rxjs": "^5.0.0-beta.12",        

        "@ngrx/core": "^1.2.0",
        "@ngrx/effects": "^2.0.0",
        "@ngrx/store": "^2.2.1",
        "@ngrx/store-devtools": "^3.2.3",
        "reselect": "^2.5.4"        
        ....
    },
}

//space.reducer.ts //space interface and reducer

export interface SpaceState {
    lastUpdated?: Date,

    spacesLoaded: boolean,
    spaces: {[key: string]: Space}
}

export const INITIAL_STATE: SpaceState = {
    lastUpdated: new Date(),

    spacesLoaded: false,
    spaces: {},
};

export const getMap = (state: SpaceState) => state.spaces;

//application.reducer.ts //composed state interface and reducer

import * as fromSpace from "./space.reducer.ts";

export interface ApplicationState{
    spaceState: SpaceState
}

export const INITIAL_APPLICATION_STATE: ApplicationState = {
    spaceState: fromSpace.INITIAL_STATE
};

const reducers = {
    spaceState: fromSpace.reducer
};

const reducer: ActionReducer<ApplicationState> = combineReducers(reducers);

export function reducer(state: any, action: any) {
    return reducers;
}

export const getSpaceState = (state: ApplicationState) => state.spaceState;
export const getSpaceMap = (state: ApplicationState) => createSelector(getSpaceState, fromSpace.getMap);

//spaces.container.ts //container component

export class SpacesComponent implement onInit() {
    constructor(private store: Store<ApplicationState>) {}

    ngOnInit(): void {
        this.store.select(getSpaceMap).subscribe(map => {
            console.log("subscribe of space-map (using shared func) from container: " + map);
        });

        this.store.select((state) => state.spaceState.spaces).subscribe(map => {
            console.log("subscribe of space-map (using container func) from container: " + map);
        });
    }
}

//output from container

subscribe of space-map (using shared func) from container: function selector(state, props) {
      for (var _len4 = arguments.length, args = Array(_len4 > 2 ? _len4 - 2 : 0), _key4 = 2; _key4 < _len4; _key4++) {
        args[_key4 - 2] = arguments[_key4];
      }

      var params = dependencies.map(function (dependency) {
        return dependency.apply(undefined, [state, props].concat(args));
      });
      return memoizedResultFunc.apply(undefined, _toConsumableArray(params));
    }

subscribe of space-map (using container func) from container: [object Object]
like image 770
skuppa Avatar asked Feb 26 '17 19:02

skuppa


1 Answers

You're calling what appears to be reselect's createSelector in your getSpaceMap selector and you are returning its result, which is why it is returning a function. Your selector is returning another selector.

Instead, you should assign the result of createSelector to getSpaceMap:

export const getSpaceMap = createSelector(getSpaceState, fromSpace.getMap);
like image 130
cartant Avatar answered Oct 22 '22 21:10

cartant