NGXS updateItem state operator
Asked Answered
B

1

9

I'm trying to use the NGXS state operators inside of my application, but I'm having trouble finding good examples of how to use them for slightly more complex updates.

For example, NGXS's documentation shows an example of updating this state:

@State<AnimalsStateModel>({
  name: 'animals',
  defaults: {
    zebras: ['Jimmy', 'Jake', 'Alan'],
    pandas: ['Michael', 'John']
  }
})

In order to change the names of one of the pandas, it uses NGXS's "updateItem" state operator like this:

@Action(ChangePandaName)
  changePandaName(ctx: StateContext<AnimalsStateModel>, { payload }: ChangePandaName) {
    ctx.setState(
      patch({
        pandas: updateItem(name => name === payload.name, payload.newName)
      })
    );
  }

In this example, the updateItem function uses a lambda expression in its first parameter to find the correct object in the array and replaces it with with the object in the second parameter.

How would you do this with an array containing complex objects of which you only wanted to change the value of one property? For instance, what if my state was this:

@State<AnimalsStateModel>({
      name: 'animals',
      defaults: {
        zebras: [{1, 'Jimmy'} , {2, 'Jake'}, {3, 'Alan'}],
        pandas: [{1, 'Michael'}, {2, 'John'}]
      }
    })

How would I use the updateItem function to locate the correct animal using the ID and then update the name?

Bridgman answered 11/3, 2019 at 19:42 Comment(0)
M
22

The default state example you provided is invalid syntax, but I think I get what you intended to provide. Something like this:

@State<AnimalsStateModel>({
  name: 'animals',
  defaults: {
    zebras: [{id: 1, name: 'Jimmy'} , {id: 2, name: 'Jake'}, {id: 3, name: 'Alan'}],
    pandas: [{id: 1, name: 'Michael'}, {id: 2, name: 'John'}]
  }
})

updateItem also accepts a state operator as a second parameter so you could use the patch operator again to modify the item. Your action would then look like this:

@Action(ChangePandaName)
changePandaName(ctx: StateContext<AnimalsStateModel>, { payload }: ChangePandaName) {
  ctx.setState(
    patch({
      pandas: updateItem(item=> item.id === payload.id, patch({ name: payload.newName }))
    })
  );
}
Maldives answered 12/3, 2019 at 7:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.