Bruno Francisco
Bruno Francisco

Reputation: 4220

Traverse a recursive array and update

I'm trying traverse an array and update the item when I find it. I have searched through Google and SO but I guess I'm not using the right keywords to do it.

Problem

I have the following object:

const form = {
  uuid: "ff17fd11-3462-4111-b083-7ff36b391c61",
  type: "form",
  items: [
    {
      uuid: "0b2dcf80-a376-4b3d-9491-0875ec24d6f7",
      type: "page",
      items: [
        {
          uuid: "23a8db85-4125-43db-ae04-d1243738972c",
          title: "Prepared by",
        },
        {
          uuid: "fb3898e0-c250-4dde-8b5c-cd2c99d181e9",
          title: "Completed at",
        }
      ],
      params: { header: true, collapsed: true }
    },
    {
      title: "",
      uuid: "e0d9d8c4-c064-4088-aad3-235b6ea1a6a1",
      type: "page",
      items: [
        {
          uuid: "73f97b99-9788-4748-82c6-7b62169f44fe",
          title: "you have been rickrolled",
        },
        {
          uuid: "46e7264c-7e95-4bbf-a4e7-7b7ab2d1ad88",
          type: "conditional_section",
          items: [
            {
              uuid: "58e5e845-d18e-4c7e-9739-a387b8144d3c",
              params: {
                title: null,
              },
            }
          ],
      ],
    }
  ]
};

Given the following object I would like to find this object in the array (being identified by uuid) and replace it with the new one:

                              👇 Heres the uuid that identifies the unique element in the array
const updatedObject = { uuid: "58e5e845-d18e-4c7e-9739-a387b8144d3c", params: { title: "new title" } };

findFormItem(form.items, updatedObject);

What I have tried so far

I have created a recursion function to update the array but for some reason the item is not being updated:

const findFormItem = (arr, item, parent = null) =>
  arr.reduce((acc, _item) => {
    if (acc) {
      return acc;
    }

    if (_item.uuid === item.uuid) {
      _item = item;
    }

    if (_item.items) {
      return findFormItem(_item.items, item, _item);
    }

    return acc;
  }, null);

Question

How can I update the array/object without having to return a new copy? I'm looking for a solution that does not alter the form of the object. The object should stay as it is, only updating the value being passed to findFormItem function

codesandbox

Upvotes: 0

Views: 242

Answers (1)

lbsn
lbsn

Reputation: 2412

If what you want is to change the original array you can just use forEach and replace the object at a given index:

const findFormItem = (arr, item) => {
  arr.forEach((element, index, arr) => {
    if (element.uuid === item.uuid) {
      arr[index] = item;
    }
    if (element.items) {
      findFormItem(element.items, item);
    }
  });
};

Upvotes: 1

Related Questions