I am new to the reactJs and therefore the MUI. I am using MUI Autocomplete to display the countries which I brought to my react-app via (country - state - city , npm package).
The autocomplete component is displaying all the countries as expected. But, I am facing problem when I select a country from one of the option and register it into the input textfield.
the 'option.name' a property of country object (from country-state-city) is not getting displayed into textfield, infact, I have to click on it exactly 2 times, to get a value into the input field?
into first time - my console is rendering 'null', and on clicking the same option very next-time, it actually render that option.name into Autocomplete's textfield.
why this is happening???
I am also using react-hook-form over the Autocomplete , since I want to send the name of the country to my API Server from this form.
here's how I got my countries into 'options'
const countries = require('country-state-city').getAllCountries();
// getAllCountries() - is a native method to bring all the countries into component.
Here's my code
Here's the fresh sandbox of my problem. Help needed, as i am stuck.
<Controller
control = {control}
defaultValue = {''} // default value of this country is empty '' string
name = {'country'} // name is of type string
rules = {{
required : 'please select a country'
}}
render = {({ field, fieldState }) => <Autocomplete
{...field}
... other properties (such as open, onOpen, onClose ...)
onChange = {( event, option : any, reason : string ) => {
if ( reason === 'selectOption' && option !== null && option.name !== '') {
field.onChange(option.name);
console.log(field.value, 'is registered');
return option.name;
}else if (reason === 'clear') {
field.onChange(null);
console.log('textfield- cleared');
}}}
clearOnBlur = {false}
value = {field.value}
options = {countries}
freeSolo = {true}
isOptionEqualToValue = {( option : any, value ) => option.name === value.name }
getOptionLabel = {( option : any ) => option.name ? option.name : '' }
renderInput = {(params) => (
<TextField
{...params}
className = {'inputField'}
label = {'Employee location'}
InputProps = {{
...params.InputProps,
sx : { fontSize : '14px' } }}
error = {!!fieldState.error}
helperText = {fieldState.error?.message}
/>
)}
/>}
/>
the name into above controller field is meant to accept a country_name ( in string form).
why am I using option.name ?, this is because our 'countries' object (from country-state-city tool) have a 'name' property, other properties are - currency : string isoCode : string lattitude : string flag : string longitude": string, ...and so on. (please view tool named as -> country-state-city ) on web for more info.
1 Answer 1
The problem is that you're setting and returning the option.name instead you should set / return the option
<Autocomplete
onChange={(event, option: any, reason: string) => {
if (reason === "selectOption" && option !== null && option.name !== "") {
field.onChange(option);
return option;
} else if (reason === "clear") {
field.onChange(null);
return null;
}
}}
/>
The reason why its logging null is because it updates the field async with onChange. If you look close it will always have the value of the option you clicked before. The initial value is null so that is why you're seeing null when you select for example Algeria. If you then click on for example Albania you'll see that the value is Algeria
1 Comment
Explore related questions
See similar questions with these tags.
field.onChangedoes not change the value immediately