2

I can't seep to find the solution to this error in my code every time I try to type something in my input field. TypeError: Cannot read property 'name' of undefined

I'm new to react and don't know too much about.

Here is all the code in my file

import React from'react';
import Notelist from '../componenets/notelist';
import { Link } from 'react-router-dom';

export default class NewPage extends React.Component {
    state = {
        note:{
            title: '',
            body: '',
            createdAt: undefined,
            updatedAt: undefined

        }
    }

    updateValue = (e) => {
        const { note } = this.state;

        this.setState({
            note: { ...note, [e.title.name]: e.target.value }
        });
    }

    handleSave = (e) => {
        e.preventDefault();

        const id = this.props.onSave(this.state.note);

        this.props.history.replace(`/notes/${ id }`);
    }

    render() {
        const { note } = this.state;

        return (
            <div className="note-form">
                <h1>New Note</h1>
                <form onSubmit={this.handleSave}>
                    <div className="note-form-field">
                        <label>Title: </label><br/>
                        <input className="input-txt" type="text" name="title" value={note.title} onChange={this.updateValue}/>
                    </div>
                    <div className="note-form-field note-form-field-text">
                        <br/>
                        <textarea name="body" value={note.body} onChange={this.updateValue} />
                    </div>
                    <div className="note-form-buttons">
                        <button className="btn">Save</button>
                        <Link to="/">Cancel</Link>
                    </div>
                </form>
            </div>
        );
    }
}

This is the full error I get:

TypeError: Cannot read property 'name' of undefined NewPage.updateValue C:/Users/user/react-notes/src/pages/new.js:20

  17 |        const { note } = this.state;
  18 | 
  19 |        this.setState({
> 20 |            note: { ...note, [e.title.name]: e.target.value }
     | ^  21 |        });
  22 |    }
  23 | 

View compiled

1
  • Hi Din, please try my solution below and let me know if that helps :) Commented Aug 16, 2019 at 6:31

4 Answers 4

2

The event object (e) does not have a key called title which is why you get "Cannot read property name of undefined".

You need event.target, which refers to the element that is causing this event to occur.

Try the following to dynamically update a state-value. It will find a key that matches the name of the element, and give it the value coming to that element (like user input):

updateValue = (e) => {
    const { note } = this.state;

    this.setState({
        note: { ...note, [e.target.name]: e.target.value }
    });
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you very much for explaining and helping me out. Your solution worked! Thanks again!
@DinSpataj you're very welcome! I'm glad this was helpful to you :)
1

I believe you are trying to assign title as key and value of the input field as value. why don't you just try this?

updateValue = (e) => {
        const { note } = this.state;

        this.setState({
            note: { ...note, "title": e.target.value }
        });
    }

Comments

1

the param e in the updateValue method is event object, it will not have a property called title.name. If you want to store the value of the title textbox to the property title of note object So your code can be like this

this.setState({
      note: { ...note, title: e.target.value }
    });

Comments

0

import React, { Component } from 'react'

export class Todolist2 extends Component {

state={name:'',items:'',price:'',arr:[],errors:{name:'',items:'',price:''}}

todoSubmit=(event)=>
{
    event.preventDefault()
  let list=this.state.arr;
  let tododata={name:this.state.name, items:this.state.items, price:this.state.price};
  list.push(tododata);
  this.setState({arr:list});
  console.log(this.state.arr);

 

}


handle=(event)=>
{
    const {name,value}=event.target;
    let errors=this.state.error;
    switch(errors)
    {
        case 'name':errors.name=value.length<2?"Name must be 2 character long":'';

        case 'items':errors.items=value.length<2?"items must be 2 character long":'';

        case 'price':errors.price=value.length<2?"price must be 2 character long":'';
    }
    this.setState({errors,[name]:value})

    this.setState({[name]:value})
    console.log(this.state);
}


deldata=(ind)=>
{
    if (window.confirm('Do u want to delete'))
    {
    let list=this.state.arr;
    list.splice(ind,1);
    this.setState({arr:list});
    }
    // alert('do u want to delete');
}

render() {

    const {errors}=this.state;
    return (
        <div>
            <h1>ToDo List 2</h1>
            <form className='container' onSubmit={this.todoSubmit}>
                <div className="form-group col-md-4">
                    <label>Name:</label>
                    <input type="text" name="name"  className='form-control' onChange={this.handle}/>
                    {errors.name.length>0 && <span className='alert alert-danger'>{errors.name}</span> }
                    
                </div>
                <div className="form-group col-md-4" onChange={this.handle}>
                    <label>Items:</label>
                    <input type="text" name="items"  class='form-control'/>
                    {errors.items.length>0 && <span className='alert alert-danger'>{errors.items}</span> }
                </div>
                <div className="form-group col-md-4" onChange={this.handle}>
                    <label>Price:</label>
                    <input type="text" name="price"  class='form-control'/>
                    {errors.price.length>0 && <span className='alert alert-danger'>{errors.price}</span> }
                </div>
                <input type='Submit' value='Submit' class='btn btn-outline-success'  />
               

                <table class='table'>
                    <tr>
                        <th>S.no</th>
                        <th>Name</th>
                        <th>Items</th>
                        <th>Price</th>
                        <th>Action</th>
                    </tr>
                    {this.state.arr.map((data,ind)=>
                    
                       <tr>
                           <td>{ind+1}</td>
                           <td>{data.name}</td>
                           <td>{data.items}</td>
                           <td>{data.price}</td>
                           <td><button  class="btn btn-info btn-lg " onClick={()=>this.deldata(ind)}>delete </button></td>
                       </tr>
                    )}
                </table>

            </form>
        </div>
    )
}

}

export default Todolist2

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.