0

I am having trouble finding a way to iterate through this nested JSON data. I would like to display elements into select option list.

I store my data in a state after a request.

const [filterData, setFilterData] = useState([]);

useEffect(() => {
    ScenarioService.getFilterData().then((res) => {
      setFilterData(res.data);
      console.log(res.data);
    });
    setIsData(true);
  }, []);
{
"groups":[
      "group1",
      "group2"
   ],
"regions":[
      "region1",
      "region2"
]
}

I already tried:

<select>
      {Object.keys(filterData).map((key) => {
         return filterData[key].map((value) => {
           return <option>{key[value]}</option>;
         });
       })}
</select>
<select>
{Object.keys(filterData["regions"]).map((keyName, i) => {
   return (
     <option key={filterData[keyName]}>{filterData[keyName]}</option>
   );
})}
</select>
{filterData.regions.map((value)=>{
          return <option>{value}</option>
        })}

Last one gives my TypeError: Cannot read property 'map' of undefined.

If i try to set my state to setFilterData(res.data.regions) then i can call map() and it works, but then my state is only regions.

Result should look like: result

3
  • 2
    looks like you're way overcomplicating. You just need, for the first select, filterData.groups.map(...), where ... is a simple function to wrap the text in an <option>. (Similar to the ones you already have.) Similar for the second one, just using regions instead of groups. Commented Jul 17, 2021 at 22:25
  • If i try your solution i get error: "TypeError: Cannot read property 'map' of undefined" because i can not map through Object. I dont really know why it is happening because groups is array and it should work with map(). @RobinZigmond Commented Jul 18, 2021 at 9:39
  • 1
    I just looked again, it's because your filterData starts off, before the request resolves, as an empty array - and it needs to have those 2 properties. Try replacing const [filterData, setFilterData] = useState([]); with const [filterData, setFilterData] = useState({ groups: [], regions: [] }); Commented Jul 18, 2021 at 11:00

1 Answer 1

4

You could simplify the code duplication by using a function

const renderOpts = key => filterData[key].map(v => <option value={v}>{v}</option>)

Then to render the selects:

<select>{renderOpts('groups')}</select>

<select>{renderOpts('regions')}</select>
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for your advice, but it gives me TypeError: Cannot read property 'map' of undefined.

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.