I got an object called data and already show values as option in select now I want to show selected option via selected object, but no success:
let data = [
{id: 1, name: 'xxx'},
{id: 2, name: 'yyy'},
{id: 3, name: 'zzz'},
{id: 4, name: 'sss'},
{id: 5, name: 'vvv'},
];
let selected = [
{id: 1, name: 'xxx'},
{id: 3, name: 'zzz'},
{id: 5, name: 'vvv'},
]
<select multiple={true}>
data.map(function(Creator, index){
return (
<option key={Index}>{Creator.name}</option>
)
});
</select>
I did:
{data.map(function(Cr, In){
{selected.map(function (Creator, Index) {
return (
<option selected={Creator.name === Cr.name ? true : false} key={In}>{Cr.name}</option>
)
})}
})}
But return no option and I guess this is not best practice, how can I fix this and what is best practice?
Use a function to iterate over the options, and use find to check whether the the id and name of the option matches the same properties of an object in the selected array, and use that variable to determine whether the option should be selected or not.
In this working example I've passed the options/selected data into the Example component, and set state with the options data for convenience.
const { useState } = React;
function Example({ data, selected }) {
const [ options, setOptions ] = useState(data);
function getSelected() {
// Iterate over the options, and get the id, and name
return options.map(option => {
const { id, name } = option;
// `found` is a boolean depending on whether the option
// in the current iteration is in the selected array
const found = selected.find(obj => {
return obj.id === id && obj.name === name;
});
// And then we can return an option where selected
// is the result of that boolean, either true or false
return <option value={option} selected={found}>{name}</option>;
});
}
return (
<div>
<select multiple>
{getSelected()}
</select>
</div>
);
};
const data = [
{id: 1, name: 'xxx'},
{id: 2, name: 'yyy'},
{id: 3, name: 'zzz'},
{id: 4, name: 'sss'},
{id: 5, name: 'vvv'},
];
const selected = [
{id: 1, name: 'xxx'},
{id: 3, name: 'zzz'},
{id: 5, name: 'vvv'},
];
ReactDOM.render(
<Example data={data} selected={selected} />,
document.getElementById('react')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>
You can do something like this which will result in the solution but it will result in extra steps. To avoid running over the extra steps of checking you can make use of a dictionary.
const addList = data.map(function (Creator, index) {
let check = false;
for (let i = 0; i < selected.length; i++) {
if (selected[i].id == Creator.id) {
check = true;
break;
}
}
return (
<option key={Creator.id} selected={check}>
{Creator.name}
</option>
);
});
Below is the one using dictionary
let newobj = {};
for(let i=0;i<selected.length;i++){
newobj[selected[i].id]="selected";
}
const addList = data.map(function (Creator, index) {
return (
<option key={Creator.id} selected={newobj[Creator.id]==="selected"}>
{Creator.name}
</option>
);
});
Do not iterate selected object, just read them by Index like this selected[index]
data.map(function(Creator, index){
return (
<option selected={Creator.id === selected[index].id ? true : false}>{Creator.name}</option>
)
});