Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

reduce es6 missing nested array of object using spread

I've got a problem merging 2 sets of data by a condition. I've debugged for more than an hour but couldn't figure out why. I've created a sample below.

I have these 2 data:

const staticRockData = {
    rockTypes: [
      {
        supplierRockTypes: [
          {
            rockCodes: ["1"],
            match_id: "abc"
          },
          {
            rockCodes: ["2"],
            match_id: "abc"
          }
        ]
      }
    ]
  };

  const gatewayRockData = {
    match_id: "abc",
    rocks: [{ rock_type: "1", rates: [] }, { rock_type: "2", rates: [] }]
  };

I have this mapping logic:

let rockTypes = staticRockData.rockTypes;

  rockTypes = rockTypes.reduce((accum, rockType) => {
    const matchedSourceId = rockType.supplierRockTypes.some(
      o2 => o2.match_id === gatewayRockData.match_id
    );
    if (matchedSourceId) {
      gatewayRockData.rocks.forEach(rock => {
        const matchRockType = rockType.supplierRockTypes.some(o2 => {
          return o2.rockCodes.includes(rock.rock_type);
        });

        if (matchRockType) {
          console.log("rock.rock_type", rock.rock_type);
          rockType = {
            ...rockType,
            rock_type: rock.rock_type,
            rates: rock.rates
          };
        }
      });
    }

    accum = [...accum, { ...omit(rockType, "supplierRockTypes") }];

    return accum;
  }, []);

  return {
    rocks: rockTypes
  };

and I expected this:

rocks: [
       {
         rates: [],
         rock_type: "1"
       },
       {
         rates: [],
         rock_type: "2"
       }
     ]
   }

The current solution is missing this:

{ rates: [], rock_type: "1"}, I wonder where my mistake is.

Omit is lodash's omit function, but I don't think that's the culprit. I created a demo here:

https://codesandbox.io/s/condescending-platform-1jp9l?fontsize=14&previewwindow=tests

like image 280
Hanz Avatar asked Jan 26 '26 03:01

Hanz


2 Answers

rockType is overwritten each repeat of the loop:

rockType = {
        ...rockType,
        rock_type: rock.rock_type,
        rates: rock.rates
      };

You should store the result in another variable this way:

...
let matchedRockTypes = [];
if (matchedSourceId) {
  gatewayRockData.rocks.forEach(rock => {
    const matchRockType = rockType.supplierRockTypes.some(o2 => {
      return o2.rockCodes.includes(rock.rock_type);
    });

    if (matchRockType) {
      console.log("rock.rock_type", rock.rock_type);
      matchedRockTypes.push({
        rock_type: rock.rock_type,
        rates: rock.rates
      });
    }
  });
}
return matchedRockTypes;
...

Here is the result: https://codesandbox.io/s/tender-ritchie-i0qkt

like image 136
AzizAhmad Avatar answered Jan 28 '26 18:01

AzizAhmad


I don't know your exact requirement but I found out what is causing the issue The problem is in your reducer's forEach, which is fixed in version below:

rockTypes = rockTypes.reduce((accum, rockType) => {
    const matchedSourceId = rockType.supplierRockTypes.some(
      o2 => o2.match_id === gatewayRockData.match_id
    );
    if (matchedSourceId) {
      gatewayRockData.rocks.forEach(rock => {
        const matchRockType = rockType.supplierRockTypes.some(o2 => {
          return o2.rockCodes.includes(rock.rock_type);
        });

        if (matchRockType) {
          accum = [...accum, { rock_type: rock.rock_type,
            rates: rock.rates }];;
        }
      });
    }

    return accum;
  }, []);

More specifically line below in forEach:

if (matchRockType) {
          rockType = {
            ...rockType,
            rock_type: rock.rock_type,
            rates: rock.rates
          };
        }

Every time loop runs and it found match your it replaces your rockType content as it is an object not an array.

other solution takes an empty array outside forEach and push the contents in the inside if condition and spread it while returning.

Just saying you should consider refactoring your code.

like image 23
Arun Avatar answered Jan 28 '26 16:01

Arun