1
votes

my program loads a list of users (with jsonplaceholder data) and I am trying to make this data editable, but gives an error:

TypeError: Cannot read property 'street' of undefined

Can someone help?

class Users extends React.Component {
  constructor(){
    super();
    this.state = {
      users: [],
      displayList: 'block',
      displayForm: 'none',
      edit: false,

      userEdit: {
        id: null,
        name: "",
        email: "",
        address: {
          street: "",
          suite: "",
          city: "",
          zipcode: ""
        },
        phone: ""
      }
    }
    this.handleClick = this.handleClick.bind(this);
    this.handleChange = this.handleChange.bind(this);
  }

  componentDidMount(){
    this.getUsersList();
  }

  getUsersList(){ ... }

  getUserEdit(){ ... }

  handleClick(id){ ... }

I have difficulty making the code inside the handleChange function, possibly it could also be wrong

handleChange(event){
    const {name, value} = event.target
    this.setState({
      userEdit:{
        [name]: value
      }
    })
  }

  render(){
    if (this.state.edit === false) {
      return (
        <UsersList
          users = {this.state.users}
          displayList = {this.state.displayList}
          handleClick = {this.handleClick}
        />
      );
    }

    else {
      this.getUserEdit();
      return(
        <UserEdit
          user = {this.state.userEdit}
          displayForm = {this.state.displayForm}
          handleChange = {this.handleChange}
          handleClick = {this.handleClick}
        />
      )
    }
  }
}

Inside UserEdit.js

function UserEdit(props){
  return(
    <ul>
      <div style={{display: props.displayForm.form}} key={props.user.id}>
        <form>
          <h2>{props.user.name} </h2>
          <p>Email:
            <input
              type="text"
              name="email"
              value = {props.user.email}
              className="form-control"
              onChange={(event) => props.handleChange(event)}
            />
          </p>
          <p>Address: </p>
          <ul>
            <li>Street:
              <input
                type="text"
                name="street"
                value = {props.user.address.street}
                className="form-control"
                onChange={(event) => props.handleChange(event)}
              />
            </li>
            <li>Suite:
              <input
                type="text"
                name="suite"
                value = {props.user.address.suite}
                className="form-control"
                onChange={(event) => props.handleChange(event)}
              />
            </li>
            <li>City:
              <input
                type="text"
                name="city"
                value = {props.user.address.city}
                className="form-control"
                onChange={(event) => props.handleChange(event)}
              />
            </li>
            <li>ZipCode:
              <input
                type="text"
                name="zipcode"
                value = {props.user.address.zipcode}
                className="form-control"
                onChange={(event) => props.handleChange(event)}
              />
            </li>
          </ul>
          <p>Phone:
            <input
              type="text"
              name="phone"
              value = {props.user.phone}
              className="form-control"
              onChange={(event) => props.handleChange(event)}
            />
          </p>
        </form>
        <button onClick={() => props.handleClick()}> Save </button>
        <hr></hr>
        </div>
    </ul>
  )
}
2

2 Answers

1
votes

The error happens because props.user.address is undefined and you try to access props.user.address.street.

What you should do check it before using it.

value={props.user.address ? props.user.address.street : ''}

You should do that in other places that you have props.user.address.something.

1
votes

You need to check whether address contains street or not. On the same lines, you should also check whether user contains address or not.

One liner check could be as:

value = { props.user && props.user.address && props.user.address.street ? props.user.address.street : '' }