Reputation: 331
Each PlacesAutoComplete component needs to have inputprops, which will have onChange which points to handleChange but handleChange only setstate for address1 becuase im insure of how to update state for each individual address when each individual input has an address. So in my example i have three PlacesAutoComplete components and i want the first one to setstate for address1, the second one to setstate for address2 and the third one to setstate for address3. How would I change my code so that each individual PlacesAutoComplete sets state for the corresponding address1, address2 or address3?
class AutoCompleteForm extends React.Component {
constructor() {
super()
this.state = {
address1: '',
address2: '',
address3: ''
}
}
handleChange = (address) => {
this.setState({
address1: address,
})
}
render() {
const inputProps = {
value: this.state.address,
onChange: this.handleChange,
placeholder: "Enter a location"
}
return (
<form onSubmit={this.handleFormSubmit}>
<PlacesAutocomplete inputProps={inputProps} />
<PlacesAutocomplete inputProps={inputProps} />
<PlacesAutocomplete inputProps={inputProps} />
<button type="submit">Find Midpoint</button>
</form>
)
}
}
export default AutoCompleteForm
Upvotes: 1
Views: 2246
Reputation: 715
I had a similar situation too.
How did I solve it? Follow the steps enlisted below:
0) Declare your constructor like this:
constructor(props) {
super(props);
this.state = {
latLngObj: {}
}
}
1) Declare below function outside render() {}
handleAddressChange = (address, stateName) => {
this.setState({
[stateName]: address,
});
}
2) I had a loop of pre-selected locations so I used it like this:
<Fragment>
{
Object.keys(this.props.selectedLocations).map((i) => {
return(
<div key={i} style={{ display: 'flex', flexDirection: 'row', justifyContent: 'space-between' }}>
<label className="spacer-right">{this.state.selectedLocations[i].label}: </label>
<PlacesAutocomplete inputProps={{value: this.state[`address_${this.props.selectedLocations[i].label.toLowerCase()}`], onChange: (address) => {this.handleAddressChange(address, `address_${this.props.selectedLocations[i].label.toLowerCase()}`)}}} />
</div>
)
})
}
</Fragment>
3) Then on click of another button (in my case it was "Finish" button) we can get geocoding to get lat-long of all specified locations above:
let tempLatLngObj = this.state.latLngObj;
Object.keys(this.state).map((key, index) => {
if(key.startsWith("address_")) {
geocodeByAddress(this.state[key])
.then(results => getLatLng(results[0]))
.then(latLng => {
tempLatLngObj[key] = latLng;
this.setState({ latLngObj: tempLatLngObj }, () => {
if(index === Object.keys(this.state).length-1) {
// Your AXIOS API call or whatever operation with the final collection of data stored in latLngObj
}
})
})
.catch(error => console.error('Error', error))
}
})
I maybe late to the party with this answer but hope this answer would help someone with this same issue in future.
Thanks and best,
Rohit Paniker
Upvotes: 0
Reputation: 9408
One way would be to write 3 different functions to handle all 3 different autocomplete
like
handleChange1 = (address) => {
this.setState({
address1: address,
})
}
handleChange2 = (address) => {
this.setState({
address3: address,
})
}
However, the above one would add more code and repeat the same logic. If you can use some pattern then we can use a single function to do the logic.
Lets assume your state will address1
, address2
, address3
.
Now lets write a function that will take in two arguments. One is the actual autocompleted address and the other is state name.
handleAddressChange = (address, stateName) => {
this.setState({
[stateName]: address,
});
}
Now lets modify your render to send the state name
render() {
const inputProps = {
value: this.state.address,
placeholder: "Enter a location"
}
return (
<form onSubmit={this.handleFormSubmit}>
<PlacesAutocomplete inputProps={inputProps} onChange={(address) => {this.handleAddressChange(address, 'address1')}} />
<PlacesAutocomplete inputProps={inputProps} onChange={(address) => {this.handleAddressChange(address, 'address2')}} />
<PlacesAutocomplete inputProps={inputProps} onChange={(address) => {this.handleAddressChange(address, 'address3')}} />
<button type="submit">Find Midpoint</button>
</form>
)
}
Now this would set the respective state when onChange
is called.
Upvotes: 2