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.


Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!