How to call a ngrx selector inside an another selector (which accepts a parameter to compute)

3.6k Views Asked by At

I created two selectors

  1. To get all networks - export const getAllNetworks = createSelector(getState, state => state.networks);

  2. get devices for each network

      createSelector(getAllNetworks, network => {
        const selectedNetwork = network.filter(net => net.id === networkId);
        return selectedNetwork[0]?.allDevices;
      });
    
    

I wanted to create a third selector which uses the first selector to get networks and then uses the second selector to get additional data

export const something = createSelector(
  getAllNetworks, (networks) => {
    networks.map(

      // How can I call the selector selectNetworkDevices by passing the network ID here and get the devices [ex: selectNetworkDevices(network.id)]

    )
  }
)
1

There are 1 best solutions below

8
Andres2142 On

You can use different selectors based on others like this:

export const selectUsers = createSelector(getState, (state) => state.users);

export const selectAccounts = (accountId?: string) => 
 createSelector(getState, (state) => 
   accountId ? state.accounts[accountId] : {}
 );

export const something = (accountId?: string) => 
  createSelector(
    selectUsers,
    selectAccounts(accountId),
    (usersData, accountsData) => {
      // some logic
      return accountId ? 'an account id was provided' : 'no-id'
    }
  )

In your component you could call this selector either providing the parameter or not:

ngOnInit(): void {
  this.store.select(something());  // without parameter
  this.store.select(something('anAccountId')); // with parameter
}

More information here: link

UPDATE:

We have 2 selectors, selectAccounts and myOtherSelector. For myOtherSelector, instead of calling directly the selectAccounts selector, you can reuse its logic by calling its callback function.

export const selectUsers = createSelector(getState, (state) => state.users);

export const selectAccounts = (accountId?: string) => 
 createSelector(getState, (state) => filterAccount(state));

export const myOtherSelector = createSelector(
  selectUsers,
  (users) => {
    if (users) return users;

    // here, you are reusing the callback function related to
    // another selector
    const accountFiltered = filterAccount([]);
    return accountFiltered;
  }
)

function filterAccount(accounts): Account {
 //...some complex logic 
 // ...
 // ...
 return account[index];
}