Home > Software design >  The question is simple. I simply want to update name and address state using onChange event Handler
The question is simple. I simply want to update name and address state using onChange event Handler

Time:11-20

The moment when i start typing on my textarea input, it becomes undefined undefined undefined. The name field is updating the state but the address field didn't. So how to update the address state from onChange event handler?

constructor(){
    super();
    this.state = {
        users: {
            name: '',
            address: '',
        },
    }
    this.getOneUser = this.getOneUser.bind(this);
    this.onChangeHandler = this.onChangeHandler.bind(this);
    this.onSubmitHandler = this.onSubmitHandler.bind(this);
}
async getOneUser(){
    try{
        const {id} = this.props.match.params;
        const res = await fetch(`http://localhost:3003/users/${id}`);
        const data = await res.json();
        const {name, address} = data;
        this.setState({users: {name, address}}, () => console.log(this.state));
    }catch(err){
        console.error(err.message);
    }
}
async onSubmitHandler(e){
    e.preventDefault();
    const {id} = this.props.match.params;
    const {history} = this.props.match;
    try{
        const res = await fetch(`http://localhost:3003/users/${id}`, {
            method: 'PUT',
            headers: {'Content-Type': 'application/json'},
            body: JSON.stringify(this.state.users)
        });
        if(!res.ok) throw new Error(`could not fetch`);
        const data = await res.json();
        this.props.history.push('/');
    }catch(err){
        console.error(`${err.message}`);
    }
}
onChangeHandler(e){
    const {name, value} = e.target;
    this.setState({
        users: {...this.state.users, [name]:value}
    });
};
render(){
    const addr =  this.state.users.address;
    return <div>
        <input type='text' name='name' value={this.state.users.name} onChange={e => this.onChangeHandler(e)} className="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" />
    
        <textarea name='address' value={`${addr.street}, ${addr.city}, ${addr.zipcode}`} onChange={e => this.onChangeHandler(e)} className="form-control" placeholder="Address" id="floatingTextarea">
        </textarea>
    </div>

Here is the Screenshot

CodePudding user response:

You can handle the address case separately in onChangeHandler. You can map the first three comma-separated values to your address object and ignore others.

  onChangeHandler(e) {
    const { name, value } = e.target;

    if (name === "address") {
      const [street = "", city = "", zipcode = ""] = value.split(",");
      this.setState({
        users: {
          ...this.state.users,
          [name]: {
            street: street.trim(),
            city: city.trim(),
            zipcode: zipcode.trim()
          }
        }
      });
    } else {
      this.setState({
        users: { ...this.state.users, [name]: value }
      });
    }
  }

Remove the value you have set and give an informative placeholder.

<textarea
     name="address"
     onChange={(e) => this.onChangeHandler(e)}
     className="form-control"
     placeholder="street, city, zipcode"
     id="floatingTextarea"
></textarea>

Code sandbox => https://codesandbox.io/s/eager-frog-snv8t?file=/src/App.js

  • Related