Get value of loop options in React - reactjs

I am looping through an array of objects that return option inside a select tag. As far as I know, I can't attach event handler on the option tag, so I attached onChange handler on select tag. I can get the value of option tag by default, but as I am looping array of objects, I want to get some other values of the object as well. How do I achieve that?.
Here's the snippet of what I am doing,
<select onChange={handleChange}>
{data.map(item => {
return (
<option key={item.id} value={item.name}>
{item.name}
</option>
);
})}
</select>
How do I get for example item.age and item.address when onChange get invoked ?

I find the solution, I set the value of option tag as an object, stringify it using JSON.stringify() so I can get the whole object, and then just read it with JSON.parse()
<select onChange={handleChange}>
{data.map(item => {
return (
<option key={item.id} value={JSON.stringify(item)}>
{item.name}
</option>
);
})}
</select>

Related

Set conditional defautlValue antd

I want to set a default value (reason) on the dropdown that depends wether refundDateInput inputs has been filled.
What I currently have is:
A watch to get refundDateInput:
const refundDateInput = Form.useWatch('refundDate', form);
A conditional initialValue that depends on refundDateInput:
<Form
layout="vertical"
form={form}
onFinish={submit}
initialValues={{
reason: refundDateInput && refund,
}}
onValuesChange={() => {
validate();
}}
>
And then the actual dropdown:
<Select
disabled={watchInputFields()}
data-testid="select-reason-id"
placeholder="Select"
className={styles.fullWidth}
allowClear
dropdownMatchSelectWidth={false}
>
{Object.keys(Reason).map((key) => (
<Option data-testid="select-option-id" key={key} value={key}>
{Reason[key]}
</Option>
))}
</Select>
The conditional initalValue is not doing anything cause, well, is not initial anymore.
I need that reason to be selected if refundDate is been filled, but also, be able to change to another reason if necessary.

Use enum in react select option

I have this enum:
const SPORTS = {
FOOTBALL: 0,
GOLF: 1,
TENNIS: 2
};
I'm trying to use those values in a react select dropdown using lodash's forIn
<select onChange={(event) => this.update(event, sport.id)}>
{_.forIn(SPORTS, (key, value) => {
{
<option value={key}>{value}</option>;
}
})}
</select>;
But am getting the error:
Invariant Violation: Objects are not valid as a React child
EDIT:
Changing to _.map works but am now seeing another issue.
Before I was manually adding all the options like which worked fine:
<option value={0}>FOOTBALL</option>;
<option value={1}>GOLF</option>;
<option value={2}>TENNIS</option>;
Now using the map I get this error:
Each child in an array or iterator should have a unique "key" prop
Now when my select boxes render they are empty but I'm not sure why.
The _.forIn() function returns the iterated object, use _.map() instead:
<select onChange={(event) => this.update(event, sport.id)}>
{_.map(SPORTS, (value, key) => (
<option value={key} key={key}>{value}</option>;
))}
</select>;

How to add attribute selected to select React?

I have this code
{categories.map((category, index) => {
return(
<option value={category._id} key={index}>{category.name}</option>
)
})}
This code display all categories. And I have const product
How to make if product.category == category._id add attribute selected to select( in map function )
You can use selected={product.category == category._id} but it's not recommended, you should use the value attribute in the select tag. Reference
Try this, this should resolve your issue. I have applied the condition as per your requirement inside the map function.
{categories.map((category, index) => {
return(
product.category == category._id ? <option value={category._id} key={index} selected>{category.name}</option>: <option value={category._id} key={index}>{category.name}</option>
)
})}

React Select Dropdown disable individual options not working

I am fairly new to react, but I am trying to create a dropdown with ant-design with some of the individual options disabled based on certain IDs.All the ID data returns as expected, however, the disable logic (which I think should work) in the disable attribute seems to disable every option in the dropdown. Anyone know what could be going on?
<Select
value={this.props.value}
name={this.props.name}
className={this.props.cssClass}
disabled={this.props.disabled}
onChange={this.props.onChange}
mode="multiple"
showSearch
filterOption={(input, option) => option.props.children.toLowerCase()
.indexOf(input.toLowerCase()) >= 0}
size="large"
>
{
this.state.data.map(opt => (
<Option
disabled={this.props.multiSelect.filter(data => data.DivisionId !== opt.Id)}
key={opt.Id}
value={opt.Id}
>
{opt.Name}
</Option>
))
}
</Select>
Issue with your code is that array filter method will always return true because empty array is parsed as true.
Replace filter method with find method.

Error Rendering a React Element

I want to make a selection from a drop-down, query movies based on the selected value, map through and render them inside a react component but I got this error
A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.
Here's the code:
...
constructor(props) {
super(props)
this.state = { description: '', list: [] }
}
handleList() {
axios.get('https://facebook.github.io/react-native/movies.json')
.then(resp => this.setState({...this.state, list: resp.data})) // Trás a lista atualizada e zera a descrição
console.log(this.state.list)
}
render() {
const loop = this.state.list.map((list) => {
return(
<Grid cols='2'>
<select className="form-control" key={i}>
<option value="teste" onClick={() => this.handleList()}>{list.description}</option>
<option value="lime">Lime</option>
<option value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
</Grid>
)
});
}
There is a couple of issues with this code example.
You are not returning anything inside the render() function. (This is the main issue you are having, or at least that React is crying about)
You are, well at least initially, mapping over an empty array and
The callback of this map you are doing things like list.description even though there exists no list and no description inside of list during the initial render.
You are using the onClick for the options instead of onChange
The endpoint you are requesting returns an object and you try to map through it. This should error because map is not defined as a function of an object.
I have managed to fix the issues I have mentioned including the one you are currently having. To save energy, typing the long explanation and reason that went into fixing your issue, have a look at this demo. It contains the exact same code you have posted, but of course, fixed/working.
I think onclick event is not suitable to use in option. Better use it on select
` <select value={this.state.value} onChange={this.handleChange}>
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
`
Sicne you are rendering a list of forms to reuse the same function, I always use a closure
handleChange = (id) = () => axios
.get(`$URL/id`)
.then(r => r.data)
.then(this.setState)
render() {
return (
list.map(item => <select
key={item.id}
onChange={this.handleChange(item.id)}
>
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>))}

Resources