Search code examples
ngxs

Update NGXS state for an object inside array


I have NGXS state defined as array.

interface Sample {
 name: string;
 age: number;
}

@State<Sample[]>({
  name: 'samples',
  defaults: [] as Sample[]
})
@Injectable()
export class SampleState {
}

Now let us say I have an existing state of [{name:'abc', age: 1}, {name: 'def', age:2}]

How can I add an action that modifies the age for an Sample based on name and updates the state. If it is an object I could use simple patchState, but here state is an array so I am not sure.

  @Action(SampleActions.UpdateAge)
  updateAge(context: StateContext<Sample[]>, action: SampleActions.UpdateAge): void {    
  }

This is my defined action in SampleActions

  export class UpdateAge{
    static readonly type = '[Sample] Update Age';
    constructor(public name: string, public age: number) {}
  }

Thanks.


Solution

  • The simplest way in NGXS is to use State Operators - in this case, the provided updateItem operator.

    E.g. refactoring your state model a little

    interface SamplesStateModel { 
      samples: Sample[];
    }
    
    @State<SamplesStateModel>({
       name: 'samples' 
      }
    )
    export class SamplesState {
     
       @Action(SampleActions.UpdateAge)
       updateAge(context: StateContext<Sample[]>, action: SampleActions.UpdateAge): void { 
         const updatedSample: Sample = { name: action.name, age: action.age };
         context.setState(
            patch({
              samples: updateItem<Sample>(sample => sample.name === action.name, updateSample)
            })
         );
       }
    }