Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ngxs state operator to insert or replace item in array (upsert)

Tags:

ngxs

I'm trying to replace or insert an array item (upsert) with existing ngxs state operators. I am currently using the following iif-statement. Is there an easier way to do this?

setState(
  patch({
    contractList: iif<Contract[]>(
      contractList=>
        contractList.some(
          contract =>
            contract.id === contractId
        ),
      updateItem<Contract>(
        contract =>
          contract.id === contractId,
        patch(loadedContract)
      ),
      insertItem<Contract>(loadedContract)
    )
  })
)
like image 745
Michael Hunziker Avatar asked Sep 20 '25 01:09

Michael Hunziker


1 Answers

State operators exist but it doesn't mean you're forced to use them, right. There is a recipe called Immutability Helpers. It's going to be published to the main site in 1-2 weeks.

If we're talking about state operators then it's possible to create custom operators, that's some kind of decomposition:

function insertOrUpdateContract(id: string, loadedContract?: Contract) {
  return iif<Contract[]>(
    contracts => contracts.some(contract => contract.id === id),
    updateItem(contract => contract.id === id, patch(loadedContract)),
    insertItem(loadedContract)
  );
}

Thus there will be less code in your action handler and it will be more self-descriptive:

ctx.setState(
  patch({ contractList: insertOrUpdateContract(contractId, loadedContract) })
);

Otherwise you could have used immer library or something else preferred, that would save more code:

import { produce } from 'immer';

const state = produce(ctx.getState(), draft => {
  const index = draft.contractList.findIndex(contract => contract.id === contractId);
  // It exists then let's update
  if (index > -1) {
    draft.contractList[index] = loadedContract;
  } else {
    draft.contractList.push(loadedContract);
  }
});

ctx.setState(state);

For sure immer is an additional package for the project but it's very lightweight. It provides more declarative way to do such immutable updates. Choose what suits you best!

I would stop on some immutability helper when it comes to such complex state updates.