0

I am trying to append to an object/dictionary of sorts that adds categories and subcategories as they are found. However, each time I try to add them it seems like I just get the last element added to the nested object and overwrites the previous additions. I've tried using Object.assign() and {...obj, key:value} to no avail.

I have multiple for-loops that independently add each key:value pair after the database has been queried.

I am looking to create an object resembling this:

{
  category1: {
    subcategory1: null,
    subcategory2: null,
    subcategory3: {
      microcategory1: null
    }
  },
  category2: {
    subcategory1: null,
    subcategory2: null,
    subcategory3: null
  }
}

But am getting this instead:

{
  cooking: {
    'ranges': null
  },
  sinks: {
    'filters': null
  }
}

There should be 10+ subcategories for both cooking and sinks.

This is the code as it stands:

let categoriesDictObj = {};

for (var index = 0; index < categories.length; index++) {
  let category = categories[index];

  const subCategories = await Product.find({
    productCategory: category,
  }).distinct("productSubCategory");

  for (
    var subCatIndex = 0; subCatIndex < subCategories.length; subCatIndex++
  ) {
    let subCategory = subCategories[subCatIndex];

    const microCategories = await Product.find({
      productMicroCategory: subCategory,
    }).distinct("productMicroCategory");


    // categoriesDictObj[category] = { [subCategory]: null };

    // Object.assign(categoriesDictObj, {
    //   [category]: { [subCategory]: null },
    // });

    categoriesDictObj = {
      ...categoriesDictObj,
      [category]: {
        [subCategory]: subCatIndex
      },
    };
  }
}
3
  • 1
    You're missing [category]: { ...categoriesDictObj[category], [subCategory]: subCatIndex } in the inner object, otherwise you're always overwriting the category object with a completely new one and only the last (with a single subCategory key) will prevail. Commented Dec 30, 2022 at 2:06
  • Why are you not using microCategories for anything? Commented Dec 30, 2022 at 2:07
  • @Bergi, microCategories dont exist yet but they will in future. I want to have it as a placeholder when additions can be made. Commented Dec 30, 2022 at 2:08

1 Answer 1

1

You're missing to spread the previous categoriesDictObj[category] in the inner object, otherwise you're always overwriting the category object with a completely new one and only the last (with a single subCategory key) will prevail.

categoriesDictObj = {
  ...categoriesDictObj,
  [category]: {
    ...categoriesDictObj[category],
    [subCategory]: subCatIndex
  },
};

However, there's no need to make it that complicated. Just create the inner object, fill it in the inner loop, and then assign it as part of the categoriesDictObj in the outer loop:

const categories = …;
const categoriesDictObj = {};

for (let index = 0; index < categories.length; index++) {
  const category = categories[index];
  const subCategories = …;

  const subCategoriesDictObj = {};
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  for (let subCatIndex = 0; subCatIndex < subCategories.length; subCatIndex++) {
    const subCategory = subCategories[subCatIndex];
    const microCategories = …;

    subCategoriesDictObj[subCategory] = subCatIndex;
//  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  }
  categoriesDictObj[category] = subCategoriesDictObj;
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}

You could also make the variables mutable and keep the objects immutable by replacing the subCategoriesDictObj[subCategory] assignment with

subCategoriesDictObj = {
  ...subCategoriesDictObj,
  [subCategory]: subCatIndex
};

and the categoriesDictObj[category] asssignment with

categoriesDictObj = {
  ...categoriesDictObj,
  [category]: subCategoriesDictObj
};

but that's really just pointless inefficiency.

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

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.