Home > OS >  How to update deeply nested array of objects?
How to update deeply nested array of objects?

Time:09-13

I have the following nested array of objects:

const data = [
  {
    product: {
      id: "U2NlbmFyaW9Qcm9swkdWN0OjEsz",
      currentValue: 34300,
    },
    task: {
      id: "R2VuZXJpY1Byb2R1Y3Q6MTA",
      name: "My Annuity",
    },
    instrumentDetails: [
      {
        instrument: {
          id: "U2NlbmFyaW9JbnN0cnVtZW50OjEz",
          supplier: {
            id: "U3VwcGxpZXJJbnN0cnVtZW50OjUzNjQ",
            supplierDetails: {
              name: "Local - Class A",
            },
          },
          currentValue: 44323,
        },
        assets: {
          current: 1.2999270432626702,
          fixed: 0.5144729302004819,
          financial: 0.0723506386331588,
          cash: 0.00006003594786398524,
          alternative: 0.05214078143244779,
          property: 0.548494862567579,
          local: 0.10089348539739094,
          global: 0,
        },
      },
    ],
  },
  {
    product: {
      id: "U2NlbmFyaW9Qcm9swkfefewdWN0OjEsz",
      currentValue: 3435300,
    },
    task: {
      id: "R2VuZXJpYfewfew1Byb2R1Y3Q6MTA",
      name: "Living",
    },
    instrumentDetails: [
      {
        instrument: {
          id: "U2NlbmFyadewwW9JbnN0cnVtZW50OjEz",
          supplier: {
            id: "U3VwcGxpZdwdwXJJbnN0cnVtZW50OjUzNjQ",
            supplierDetails: {
              name: "Local - Class B",
            },
          },
          currentValue: 434323,
        },
        assets: {
          current: 1.294353242,
          fixed: 0.514434242004819,
          financial: 0.07434286331588,
          cash: 0.0000434398524,
          alternative: 0.05242348143244779,
          property: 0.543242567579,
          local: 0.100432439739094,
          global: 0,
        },
      },
    ],
  },
];

The above data presents an array of products which consist of instruments that are described in instrumentDetails array. I am trying to find an instrument by supplier id and update its assets by multiplying all of the asset values by a given number.

Here is my function:

export const updateObject = (
  productsArr: any,
  supplierInstrumentId: string
) => {
  return productsArr.map(
    (product: any) => {
      product.instrumentDetails.map(
        (instrumentDetail: any) => {
          if (
            instrumentDetail.instrument.supplier.id ===
            supplierInstrumentId
          ) {
            instrumentDetail.assets.current = instrumentDetail.assets.current   5;
            instrumentDetail.assets.fixed= instrumentDetail.assets.fixed  5;
            instrumentDetail.assets.financial= instrumentDetail.assets.financial  5;
            instrumentDetail.assets.cash= instrumentDetail.assets.cash  5;
          }
        }
      );
    }
  );
};

This function is giving an error :

Uncaught TypeError: Cannot assign to read only property 'current' of object '#'

How can I deeply update the above data? Please help.

CodePudding user response:

You need to return a new instrumentDetail-type object from the map function. Don't try to update the existing object.

(instrumentDetail: any) => {
  const assets = instrumentDetail.instrument.supplier.id === supplierInstrumentId
    ? Object.fromEntries(
      Object.entries(instrumentDetail.assets).map(([k, v]) => [k, v   5])
    )
    :
    instrumentDetail.assets;
    
  return {
    ...instrumentDetail,
    assets
  };
}

CodePudding user response:

Your product map is not returning which is why you're likely getting an undefined. I wasn't getting the typescript error which you mentioned above. This should leave the array in the state at which you intended.

const updateObject = (
  productsArr: any,
  supplierInstrumentId: string
) => {
  return productsArr.map(
    (product: any) => {
      product.instrumentDetails.map(
        (instrumentDetail: any) => {
          if (
            instrumentDetail.instrument.supplier.id ===
            supplierInstrumentId
          ) {
            instrumentDetail.assets.current  = 5;
            instrumentDetail.assets.fixed= instrumentDetail.assets.fixed  5;
            instrumentDetail.assets.financial= instrumentDetail.assets.financial  5;
            instrumentDetail.assets.cash= instrumentDetail.assets.cash  5;
            return instrumentDetail;
          }
        }
      );
      return product;
    }
  );
};
  • Related