0

I have a JSON file :

[
  {
    "level_1": "music",
    "level_2": "rock",
    "level_3": "had-rock / metal"
  },
  {
    "level_1": "music",
    "level_2": "rap",
    "level_3": "rapcore / rap-west-coast"
  },
  {
    "level_1": "music",
    "level_2": "country",
    "level_3": "contry-rock / country-pop"
  }
]

I want render a select, for this I call my json file:

const [musicType, setMusicType] = useState([]);

useEffect(() => {
    axios
        .get("https://www.musictype")
        .then(function (response) {
            setMusicType(response.data);
        })
        .catch(function (error) {
    console.log('request failed', error)
  })
}, []);

And i create a map function on the return :

<select>
  <option value="" placeholder="Selection">Selection</option>
  {musicType.map((type, index) => (
  <option key={index}>{type.level_3}</option>))}
</select>

But it isn't render alphabetically, if I Use sort() React display an error:

<select>
  <option value="" placeholder="Selection">Selection</option>
  {musicType.sort((a,b) => (
  <option key={index}>{a.level_3.localeCompare(b.level_3)}</option>))}
</select>

"Error: valid as a React child (found: object with keys {level_1, level_2, level_3}). If you meant to render a collection of children, use an array instead."

gcbox999
  • 147
  • 8
  • Does this answer your question? [Sort array of objects by string property value](https://stackoverflow.com/questions/1129216/sort-array-of-objects-by-string-property-value) – Nick Parsons Apr 15 '21 at 11:25

2 Answers2

1

Compare function passed to sort method should follow the doc which return 0 or 1 or -1 defining the order

So here you should sort it separately and then map for elements to be rendered afterward

<select>
  <option value="" placeholder="Selection">Selection</option>
  {musicType
     .sort((a,b) => a.level_3.localeCompare(b.level_3))
     .map((type, index) => (
       <option key={index}>{type.level_3}</option>
     ))
  }
</select>
hgb123
  • 13,869
  • 3
  • 20
  • 38
0

First sort then map to a single string. Try this,

            <select>
                <option value="" placeholder="Selection">
                    Selection
                </option>
                {musicType
                    .sort((a, b) => {
                        a = a.level_3.toLowerCase();
                        b = b.level_3.toLowerCase();
                        return a < b ? -1 : a > b ? 1 : 0;
                    })
                    .map((type, index) => (
                        <option key={index}>{type.level_3}</option>
                    ))}
            </select>


NOTE: You can sort by any property of the JSON. Just change a.level_1 and b.level_1 instead of the level_3.

Amila Senadheera
  • 12,229
  • 15
  • 27
  • 43