javascriptnestedmaps

Mapping arrays of objects conditionally in Javascript


I have array of objects with a multi-level nesting.

const switches = [{
  orgId: "1111a7cd-0d58-11ef-83a2-06a19a0b1f5d",
  orgName: "Management 1",
  orgType: 2,
  organisations: [],
  features: [{
    name: "AdvancedAdminApprovalLevels",
    type: "feature",
    category: "Management Features",
    value: false,
  }, {
    name: "AdminCategoryApprovalByRole",
    type: "feature",
    category: "Management Features",
    value: false,
  }],
}, {
  orgId: "2222a7cd-0d58-11ef-83a2-06a19a0b1f5d",
  orgName: "Management 2",
  orgType: 2,
  organisations: [{
    orgId: "33333f59a-4976-11ed-af5d-021feb88a3f6",
    orgName: "Submanagement ",
    orgType: 2,
    features: [{
      name: "AdvancedAdminApprovalLevels",
      type: "feature",
      category: "Management Features",
      value: false,
    }, {
      name: "AdminCategoryApprovalByRole",
      type: "feature",
      category: "Management Features",
      value: false,
    }],
  }],
  features: [{
    name: "AdvancedAdminApprovalLevels",
    type: "feature",
    category: "Management Features",
    value: false,
  }, {
    name: "AdminCategoryApprovalByRole",
    type: "feature",
    category: "Management Features",
    value: false,
  }],
}, {
  orgId: "4444a7cd-0d58-11ef-83a2-06a19a0b1f5d",
  orgName: "Management 3",
  orgType: 2,
  organisations: [],
  features: [{
    name: "AdvancedAdminApprovalLevels",
    type: "feature",
    category: "Management Features",
    value: false,
  }, {
    name: "AdminCategoryApprovalByRole",
    type: "feature",
    category: "Management Features",
    value: false,
  }],
}];

What I want is the function to map it to new array where if the string provided === name in features array objects then value should be changed to the value provided in parameter.

So if I call the function like

handleTopLevelToggle('AdvancedAdminApprovalLevels', true);

I should return the same nested arrays but with value changed to true for all the with name 'AdvancedAdminApprovalLevels', on all nested levels.

Te solution I've started with was

const handleTopLevelToggle = (value, fSwitch) => {
  const mappedArray = switches.map((swtch) => {
    swtch.features.map((feature) => {
      if (feature.name === fSwitch) {
        return { ...swtch, value: value };
      }
      return swtch;
    });
  });

  return mappedArray;
};

Solution

  • Your current solution is on the right track, but it has a few issues.

    1. You are not returning anything from the outer map function, which will result in undefined values in your mappedArray.
    2. You are not handling the nested organisations array.
    3. You are replacing the entire swtch object with a new value, instead of just updating the value property of the matching feature.

    Revised Function:

    const handleTopLevelToggle = (fSwitch: string, value: boolean) => {
      const mapFeatures = (features) => {
        return features.map((feature) => {
          if (feature.name === fSwitch) {
            return { ...feature, value: value };
          }
          return feature;
        });
      };
    
      const mapOrganisations = (organisations) => {
        return organisations.map((org) => {
          return { ...org, features: mapFeatures(org.features) };
        });
      };
    
      const mappedArray = switches.map((swtch) => {
        return {
          ...swtch,
          features: mapFeatures(swtch.features),
          organisations: mapOrganisations(swtch.organisations),
        };
      });
    
      return mappedArray;
    };