0
const displayDataTypes = [];
const TypeMap = {
  data: ['type2', 'type3'],
};
  
const Type = {
  title: 'Type',
  values: [
    { label: 'Type-1', value: 'type1', disabled: false },
    { label: 'Type-2', value: 'type2', disabled: false },
    { label: 'type-3', value: 'type3', disabled: false },
    { label: 'type-4', value: 'type4', disabled: false },
    { label: 'type-5', value: 'type5', disabled: false }
  ]
};
  
const TypesSelection = TypeMap['data'];  
  
Type.values.forEach((item) => {
  const tmp = Object.create(item);
  TypesSelection.forEach((type) => {
    if (tmp.value !== type) {
      tmp.disabled = true;
    }
  });
  displayDataTypes.push(tmp);
});
  
console.log(displayDataTypes);

In the above code, Every object property disabled is getting true. I need the type2 and type3 should be false and rest should be true because of TypeMap - data. So the output should be

[
  { label: 'Type-1', value: 'type1', disabled: true  },
  { label: 'Type-2', value: 'type2', disabled: false },
  { label: 'type-3', value: 'type3', disabled: false },
  { label: 'type-4', value: 'type4', disabled: true  },
  { label: 'type-5', value: 'type5', disabled: true  }
]

3 Answers 3

1

Try it using the Array.map function:


const output = Type.values.map(v => {
  v.disabled = !TypesSelection.includes(v.value);
  return v;
})

console.log(output)

This is not only smaller but more readable.

The learn more about the Array.map function: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

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

1 Comment

Thank you so much. This is a nice solution. But wanted to know my mistake in the above code and want the solution with this approach also.
0

The issue is in the iteration. At some point tmp.value will be 'type2' and type will be 'type3'. This will cause disabled to get set to true for the 'type2' object.

I think this does what you want.

const Type = {
  title: 'Type',
  values: [
{
  label: 'Type-1',
  value: 'type1',
  disabled: false,
},
{
  label: 'Type-2',
  value: 'type2',
  disabled: false,
},
{
  label: 'type-3',
  value: 'type3',
  disabled: false,
},
{
  label: 'type-4',
  value: 'type4',
  disabled: false,
},
{
  label: 'type-5',
  value: 'type5',
  disabled: false,
},
  ],
};
  
const TypeMap = {
  data: ['type2', 'type3']
};
  
const TypesSelection = TypeMap['data'];
const displayDataTypes = Type.values.map(item => {
  const shallowCopy = {...item};
  if (TypesSelection.every(type => (type !== shallowCopy.value))) {
shallowCopy.disabled = true;
  }
  return shallowCopy;
});
  
console.log(displayDataTypes);

I would recommend not using a property named "disable" because it causes confusing double negative situations. Instead use "enabled". This is of course assuming you have control of the property names.

If you don't need to preserve the initial "disabled" states on the copies and if you don't need copies then use the much smaller / simpler implementation in Ilijaz's answer.

Comments

0

Your code is failing because the correct result is being overwritten by other iterations of your inner loop.

Your current structure is 2-step:

  1. Loop over each value in Type.values
  2. Loop over each value in TypeMap.data and check if the two elements don't match

As a result of that second step, even elements that match will get compared to another element that doesn't match, causing the conditional code to get executed anyway.

Eg.:

  1. Outer loop:
    1. item is type2
  2. Inner loop:
    1. type is type2
    2. check the condition: type2 !== type2 is false
    3. Skip conditional code
  3. Inner loop
    1. type is now type3
    2. check the condition: type3 !== type3 is true
    3. run conditional code, set disabled to true

As such, all disableds will always be set to true.


Using a nested forEach isn't very well suited for this use case, since there's no straightforward way to avoid this problem. If you still want to use forEach for the outer loop, you can, or you could simplify further with map(), as @Ilijaz suggested in another answer.

Using forEach and Array.prototype.includes:

const displayDataTypes = [];

const TypeMap = {
  data: ['type2', 'type3'],
};

const Type = {
  title: 'Type',
  values: [{
      label: 'Type-1',
      value: 'type1',
      disabled: false,
    },
    {
      label: 'Type-2',
      value: 'type2',
      disabled: false,
    },
    {
      label: 'type-3',
      value: 'type3',
      disabled: false,
    },
    {
      label: 'type-4',
      value: 'type4',
      disabled: false,
    },
    {
      label: 'type-5',
      value: 'type5',
      disabled: false,
    },
  ],
};

const TypesSelection = TypeMap['data'];

Type.values.forEach((item) => {
  const tmp = Object.create(item);
  if (!TypesSelection.includes(tmp.value)) {
    tmp.disabled = true;
  }
  displayDataTypes.push(tmp);
});

console.log(displayDataTypes);
.as-console-wrapper {
  max-height: 100% !important;
}

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.