michaelkrone / ngrx-normalizr

Managing normalized state in ngrx applications - transparently
https://michaelkrone.github.io/ngrx-normalizr/
MIT License
50 stars 17 forks source link

issue or question : How to work in feature module with feature store #34

Closed yd021976 closed 6 years ago

yd021976 commented 6 years ago

Hi and great job for this library !

All is fine, except i can't work with ngrx-normalizr "selectors" correctly when i put it in a feature module.

Example : I have a store made of 2 feature modules (user and templates), so the root store structure is like this :

{
user : IUser,
templates : {normalized, other props...}
}

So, in my template feature module, i define selectors like this :

const templateFeatureSelector = createFeatureSelector<template_state.ITemplates>('templates');
/** 
 * Get all templates
*/
const templateSchemaSelector = createSchemaSelectors<template_model.ITemplate>(template_model.schemas);
const getAllTemplates = createSelector(templateFeatureSelector,templateSchemaSelector.getNormalizedEntities, templateSchemaSelector.entitiesProjector);

and then in the feature module component, i do this to get all "templates" :

constructor(private store: Store<any>) {
    this.templates$ = this.store.select(templates_selectors.templates.getAllTemplates);
    this.templates$.subscribe((data) => {
      let a = 0;
    });

  }

It doesn't work since the data value in "subscribe" is always returnin the "full" store object.

After few tests, i get that in my selector the input of "createFeatureSelector" is never take into account, it is always ignored. So, in normalizr.js, the "state" passed to the "getNormalizedState" selector is alway the root Store (with both "user" and "templates" parts) and never the feature module store (only "templates" part)

At this time, the only workaround i found is to do this when i want to select data in my component : this.templates$ = this.store.select(templates_selectors.templates.feature).select(templates_selectors.templates.getAllTemplates); ==> I must first select the "feature" store slice, then obtain the correct store, then select against this store with ngrx-normalizr "createSchemaSelector" utility to get my data.

Is this by design or am I wrong ?

Thank you

yd021976 commented 6 years ago

self reply : Don't mind, this question is about "createselector" in ngrx and in particularly it's about my knowledge about selectors :-(

So, i solved this problem by creating 2 selectors. My error was that i was thinking that i could wrap all in only one selector.

The correct way to get denormized objects in my example above is :

const templateFeatureSelector = createFeatureSelector<template_state.ITemplates>('templates');
/** 
 * Get all templates
*/
const templateSchemaSelector = createSchemaSelectors<template_model.ITemplate>(template_model.schemas);
const templateEntities = createSelector(templateFeatureSelector, templateSchemaSelector.getNormalizedEntities);
const getAllTemplates = createSelector(templateEntities,templateSchemaSelector.entitiesProjector);

So I close this issue. Sorry.