0

Let's say I have a list of products that can be filtered by type when user selects a different type from a dropdown (there are other filters users can set as well but they aren't relevant to this example).

I have State A that holds the currently filtered products. State B holds the currently selected type.

When user changes a type, I want it to also update the currently filtered products.

What is the proper way to do this?

  • I could call a 'set' action on State A from State B whenever State B is set
  • I could call a 'set' action on both State A and State B when a user sets State B
  • I could listen to State B in State A and update State A when State B changes
  • I could just have the type in State A as well, but I use the type for other separate states for other features as well
connorvo
  • 761
  • 2
  • 7
  • 21

1 Answers1

1

Assuming you don't want to / can't have selected type value on State A, I'd suggest a Selector on state A that depends on the state B values.

In state A:

@Selector([StateB])
static filterProducts(stateA: StateAModel, stateB: StateBModel) { 
  return stateA.products.filter(p => p.type === stateB.type);
}

This will be reevaluated whenever stateB changes (or state A by default in the current NGXS release). A further refined way would be having a type selector on state B.

In state B:

static @Selector()
selectedType(state: StateBModel) { 
  return state.type;
}

Then use that selector in state A:

@Selector([StateB.selectedType])
static filterProducts(stateA: StateAModel, selectedType: any) { 
  return stateA.products.filter(p => p.type === selectedType);
}

This way selectors will fire when the state changes and you don't need to add further actions.

Garth Mason
  • 7,611
  • 3
  • 30
  • 39
  • Thanks for the answer! This isn't quite what I want because then I still have to have ALL products stored in State A and then just filtering them. I want to read data from JSON files based on the selected type (I have a json file for products Type A, products Type B, etc). I currently am just changing State A and State B when the user changes the type in the dropdown, but was hoping there was a way to change State A when state B changes automatically. – connorvo Aug 04 '20 at 16:08
  • 1
    Any reason not to have all products in the store? If you want to stick with your current state model, then another option could be to subscribe have State A subscribe to changes in State B using `ngxsOnInit` in State A – Garth Mason Aug 05 '20 at 02:25
  • Seems like it could slow down filtering if I have all products in there. Just recently figured out about lifecycle hooks which seems like the move – connorvo Aug 05 '20 at 03:05
  • I'd suggest start with them all in state as first option (unless it's clearly an enormous load of products then you could look at a paging style API to update the state, triggered by an action). If you've got it all in state then everything will be a lot simpler from there on and you can just use selectors to project the data your components want to consume. – Garth Mason Aug 05 '20 at 05:03