0

I have the reducer that contains some of the list objects.

const list = [
  {
    name: 'A',
    products: { items: [] },
  },
  {
    name: 'B',
    products: { items: [{ qty: 1 }] },
  },
]

I want to add new items to the product key. reducer

export const addProductToSubscription = (state, { name, products }) => ({
  ...state,
  list: state.list.map((v) =>
    name === v.subscriptionName ? [...v.products, { ...v.products, items: products }] : v
  ),
})

disptach like this,

dispatch("A",[{qty:2}])

expected output

const list = [
  {
    name: 'A',
    products: { items: [{ qty: 2 }] },
  },
  {
    name: 'B',
    products: { items: [{ qty: 1 }] },
  },
]

What reducer not updating the state.

Thanks!!

4
  • Does the state has a list key or the list is the state? Commented Jul 9, 2021 at 12:31
  • arr.map does not mutate the array, it returns a new array. That might change what you're trying to do in the second code block. Commented Jul 9, 2021 at 12:32
  • yes state has the list key Commented Jul 9, 2021 at 12:35
  • why this is not updating state Commented Jul 9, 2021 at 12:37

3 Answers 3

1

I've recreated your environment and end up like-

const state = {
    list: [
        {
            name: "A",
            products: { items: [] },
        },
        {
            name: "B",
            products: { items: [{ qty: 1 }] },
        },
    ],
};

const updateState = (state, { name, products }) => {
    return {
        ...state,
        list: state.list.map(v => {
          return {
            ...v,
            products: {
              ...v.products,
              items: [
                ...v.products.items,
                ...products
              ]
            }
          }
        }),
    };
};

const res = updateState(state, { name: "A", products: [{ qty: 2 }, {qty: 4}] });

console.log(JSON.stringify(res));
.as-console-wrapper{min-height: 100%!important; top: 0}

Sign up to request clarification or add additional context in comments.

Comments

1

A more advanced solution than Object.assign and spread operator(...) - immutability-helper

const update = require('immutability-helper');
const assert = require('assert');

const list = [
  {
    name: 'A',
    products: { items: [] },
  },
  {
    name: 'B',
    products: { items: [{ qty: 1 }] },
  },
];

function addProductToSubscription(state = list, { name, products }) {
  return update(state, {
    $apply: (self) => {
      return self.map((v) => {
        if (v.name === name) {
          return update(v, { products: { items: { $push: products } } });
        }
        return v;
      });
    },
  });
}

const actual = addProductToSubscription(undefined, { name: 'A', products: [{ qty: 2 }] });

console.log(JSON.stringify(actual, null, 2));

assert(actual !== list, 'new copy');
assert(actual[0] !== list[0], 'new copy for A object');
assert(actual[0].products !== list[0].products, 'new copy for A object products');
assert(actual[0].products.items !== list[0].products.items, 'new copy for A object products items');

Output:

[
  {
    "name": "A",
    "products": {
      "items": [
        {
          "qty": 2
        }
      ]
    }
  },
  {
    "name": "B",
    "products": {
      "items": [
        {
          "qty": 1
        }
      ]
    }
  }
]

Comments

0

Take the new copy using spread operator and update to the state

export const addProductToSubscription = (state, { name, products }) => ({
  ...state,
  list: state.list.map((v) =>
    v.name === name
      ? {
          ...v,
          products: { items: [...v.products.items, ...products] },
        }
      : v
  ),
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.