0

whenever I want to create a new To Do without changing anything in the HTML and push() the array it works fine, but as long as I trigger the onChange event listener I get the "this.state.tasks.map is not a function". Can't figure out what could be the possible issue.

    import React, { Component } from 'react';
    import './CreateTask.css'
    import CreatedTask from '../CreatedTask/CreatedTask';
    import Aux from '../../hoc/Aux';

        class CreateTask extends Component {
            constructor(props){
                super(props);
                this.state = {
                    tasks : [
                        {member : '',
                         toDo : '',
                         dod : '',
                         time : ''
                        }
                    ],
                    showTask : false
                };
                this.changeHandler = this.changeHandler.bind(this);
                this.submitTask = this.submitTask.bind(this);



            }

// onCHANGE HANDLER 

            changeHandler = (event) => {
             this.setState(
                {   
                    tasks: {[event.target.name] : event.target.value}
                }
             ) 
            }
            clearFields = () => {
                this.setState({
                    tasks : [
                        {member : '1212',
                         toDo : '1331',
                         dod : '121',
                         time : ''
                        }
                    ],
                    showTask : false
                })
            }
            submitTask=(event)=>{
                this.setState({showTask:true});
                let tasks = this.state.tasks;
                tasks.push({
                    tasks: {[event.target.name] : event.target.value}
                })  
            }

            render() {
// STARTS HERE       
                    let tasksubmit = null;
                    if(this.submitTask){
                    tasksubmit = 

                        <div>
                            {this.state.tasks.map( task => {
                                return <CreatedTask
                                    member = {task.member}
                                    todo = {task.toDo}
                                    dod = {task.dod}
                                    time = {task.time}
                                /> 

                            })}
                        </div>
                     }
// ENDS HERE
                console.log(tasksubmit);
            return(
                <div>
                    <div className="CreateTask">
                        <p>Group member:
                        <select id="groupMember" 
                            onChange={this.changeHandler}
                            name="member"
                            >
                                <option defaultValue='' selected disabled>Select group member</option>
                                <option value="Berin">Berin</option>
                                <option value="Raddy">Raddy</option>
                                <option value="Ventsi">Ventsi</option>
                                <option value="Cristian">Cristian</option>
                        </select>          
                        </p>
                        <p>To do:<input 
                                    type="text" 
                                    id="toDo"
                                    name="toDo" 
                                    value={this.state.toDo} 
                                    onChange={this.changeHandler}>
                                 </input>
                        </p>
                        <p>Definiton of done:
                            <textarea 
                                id="dod" 
                                name="dod"
                                value={this.state.dod} 
                                onChange={this.changeHandler}>
                            </textarea>
                        </p>
                        <p>Average time required(hours):
                            <input 
                                value = {this.state.time}
                                onChange = {this.changeHandler}
                                type="number" 
                                min="0" 
                                id="time" 
                                name="time">
                            </input>
                        </p>
                        <div>
                        <button type="submit" onClick = {this.clearFields}>Cancel</button>
                        <button type="submit" onClick = {this.submitTask}>Create</button>
                        </div>

                    </div>
                    {tasksubmit}

                </div>
            );
            } }

        export default CreateTask;

I am still new to React, and I know that I should bind() some functions to the constructor, but I do not know how to bind this.

1
  • Your submitTask is very odd (and modifies state directly, pretty much a no-no). Commented Oct 8, 2018 at 20:18

1 Answer 1

1

The first time you call setState in your changeHandler function you are setting tasks to be an object. Therefore it's no longer an array anymore and objects can't be iterated over with Array.map.

See here:

changeHandler = (event) => {
    this.setState({   
        tasks: {[event.target.name] : event.target.value} // Your setting to an object here. Tasks was an array and here you change it to {name: value}
    });
}

You can change to something like this:

changeHandler = (event) => {
    let memberTasks = this.state.tasks.filter((task) => task.member === event.target.value)
    this.setState({
        tasks: memberTasks
    })
}
Sign up to request clarification or add additional context in comments.

4 Comments

First of all, thank you for your answer sir! Much appreciated! Might be a stupid question but how can I set it to be an array in this case? I am very beginner to JavaScript and React, so I would highly appreciate your help.
You probably just want to use a filter function and only return the todos that belong to the correct person. Something along these lines let newTasks = this.state.tasks .filter((task) => task.member === event.target.value) See my edited answer.
Thank you for your help, and currently I don't see any errors, though now I can not get any data from CreateTask component. Previously, when I was using [ tasks: {[event.target.name] : event.target.value} ] I could successfully gather data, though there was no map() function and it was only single component.This is how my project looks like : imgur.com/a/cvMMpQ1
Hi, I'd just recommend you follow a few React todo tutorials from the web. There are dozens of good ones to choose from. Try picking something that has been updated in the past year. Good luck!

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.