Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Selectors with parameters #8

Closed
oemmes opened this issue Sep 11, 2019 · 6 comments
Closed

Selectors with parameters #8

oemmes opened this issue Sep 11, 2019 · 6 comments

Comments

@oemmes
Copy link

oemmes commented Sep 11, 2019

Hello,

thank you for the Duck classes which offer a good layer to work with the state. We use it throughout our application :)

One thing I didn't get into a duck is a selector with parameters. For example:

export const getItemByKey = createSelector(
  getItems,
  (items, data: { key: string }) => items[key]
);

When just assigning it in the Duck as a property you cannot pass the parameters and the type of the proeprty for TypeScript is "never" (because the selector type is MemoizedSelectorWithProps).

@Ducksify<ItemsState>({
  initialState: {
    items: {}
  }
})
export class ItemsDuck {
  // Not able to pass parameters, getItemByKey$ is typed as "never"
  getItemByKey$ = selectors.getItemByKey;
}

I tried to create a function but in the Duck I have no access to this.pipe or even this.store:

@Ducksify<ItemsState>({
  initialState: {
    items: {}
  }
})
export class ItemsDuck {
  getItemByKeyFromStore(key: string) {
    // this.store is not available
    return this.store.pipe(select(selectors.getItemByKey, { key }));
  }

  getItemByKeyWithPick(key: string) {
    // this.pick is not available and also does not accept MemoizedSelectorWithProps
    return this.pick(selectors.getItemByKey, { key });
  }
}

So I ended up injecting the store again in some other service class and using the original selector.

It would be nice if a selector with parameters could also be accessed using a Duck class. Any ideas?

@GregOnNet
Copy link
Member

Hi,

I need to have a look at createSelectorFactory of @ngrx/store maybe this type is ignored by the Duck yet.
But this should totally be possible.

Thanks for reaching out!

Kinds
Gregor

@Onmar
Copy link

Onmar commented Oct 28, 2019

Hi,

I have the same issue in my project.
I have a selector with properties, but Duck.pick only accepts one withouth them.

From looking at your code this is because your pickfactory only accepts selectors without props.

pick<TState, TResult>(selector: MemoizedSelector<TState, TResult>) {
    return store.pipe(select(selector));
}

This would be the pick function for a selector with props:

pick<TState, TProps, TResult>(selector: MemoizedSelectorWithProps<TState, TProps, TResult>, props: TProps) {
    return store.pipe(select(selector), props);
}

For now there is no way around it, you will have to use the store normally unfortunately.

@GregOnNet
Copy link
Member

Hi Omar,

thanks for providing the sample.
This is really useful to me.

Please give me a few days to integrate this to the duck library.
Unfortunately, my laptop is broken.
Tomorrow, I hopefully get the new one.

@GregOnNet
Copy link
Member

Hi together,

there are two different ways using parameters with selectors.
There is MemoizedSelectorWithProps & creating a higher order function (see: https://github.com/ngrx/platform/blob/57fd3d78799ac0cdd97a5cf59999595cfead6c14/modules/router-store/src/router_selectors.ts#L35).

For now, I will implement MemoizedSelectorWithProps.
Please let me know if you need further possibilities, too.

Cheers
Gregor

@GregOnNet
Copy link
Member

GregOnNet commented Dec 22, 2019

pick now accepts properties. Shipped with v8.3.0.

@GregOnNet
Copy link
Member

Closing this issue for now.
Please feel free to reopen it if you need further support for selectors taking properties.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants