2

I've got a select component built on select tag. I have an object of data:

 const options= [
    { initialValue: "abc", data: ["data5", "data55", "data555"] },
    { initialValue: "zxy", data: ["data2", "data22", "data222"] },
  ];

Here I am getting 2 dropdown components with initial value but I am not getting data after initialValue.

So basically in my select I need abc, data5, data55, data555 and zxy, data, data2, data22, data222 But I am getting abc, data5data55data555 and zxy, datadata2data222

  {options.map((val, index) => {
        return (
          <Select>
            <option value="" key={index}>
              {val.initialValue}
            </option>

              <option value={`${val}`} key={index + 1}>
                {val.data}
              </option>;
          </Select>
        );
      })}
3
  • So you want, for example, 4 options from { initialValue: "abc", data: ["data5", "data55", "data555"] }, being "abc", "data5", "data55", and "data555"? Commented Dec 29, 2020 at 8:49
  • yeap exactly and I have done the below solution which did work for me that's why I asked here Commented Dec 29, 2020 at 8:53
  • Great. Provided answer below. Commented Dec 29, 2020 at 9:12

4 Answers 4

1

Iterate the val.data by Array.map() to add several <option>.

{options.map((val, index) => {
  return (
    <Select>
      <option value="" key={index}>
        {val.initialValue}
      </option>
      
      {val.data.map((d, j) => (
        <option value={`${d}`} key={`options${index}-${j}`>
          {d}
        </option>
      )}
    </Select>
  );
})}
Sign up to request clarification or add additional context in comments.

Comments

0

You have to iterate data values also using the map.

const options = [{
        initialValue: "abc",
        data: ["data5", "data55", "data555"]
    },
    {
        initialValue: "zxy",
        data: ["data2", "data22", "data222"]
    },
];

{options.map((val, index) => {
        return (
          <Select>
            <option value="" key={index}>
              {val.initialValue}
            </option>
            {
                val.data.map((d, i) => (<option value={`${d}`} key={`${index}-${i}`}>{d}</option>))
            }
          </Select>
        );
      })}

1 Comment

this solution works, my problem was with key attribute
0

You can use Array.map() two times.

{
  options.map((item, index) => (
    <select key={index}>
      <option value={item.initialValue}>{item.initialValue}</option>
      {item.data.map((value, index) => (
        <option value={value} key={index}>
          {value}
        </option>
      ))}
    </select>
  ))
}

Comments

0

I suggest flattening your options first, then mapping the options using a single array and key set. It still "double maps" like several of the other answers here but does so in a more functional programming way, i.e. the second mapping isn't nested. It's a bit more DRY and (subjectively) easier to read IMO.

array.prototype.flatMap

Map each set of options to a single array (i.e. initialValue and data spread into it) value which is then overall flattened down to a single array of all the option values.

<select>
  {options
    .flatMap(({ initialValue, data }) => [initialValue, ...data])
    .map((option, index) => (
      <option key={index} value={option}>
        {option}
      </option>
    ))}
</select>

Edit how-can-i-map-array-of-strings-in-my-select-component

2 Comments

why do you suggest that?
@Sonny49 Ah, basically just answered that just before you commented. It's more DRY as there is only a single function now creating option tags. I also believe it is easier to read since the logic flow has now been flattened, no nesting to read into.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.