React Datepicker - Uncaught RangeError: Invalid time value

Viewed 12

Building a simple ToDo list app in ReactJS. Below is my Add Task functional component:

import React, { useState } from "react";
import TaskDataService from "../services/task.service";
import DatePicker from 'react-datepicker'
import FadeIn from 'react-fade-in';

import "react-datepicker/dist/react-datepicker.css";
import 'bootstrap/dist/css/bootstrap.min.css';

const AddTask = () => {
    const initialTaskState = {
        id: null,
        title: "",
        description: "",
        completed: false,
        startDate: new Date()
    };
    const [task, setTask] = useState(initialTaskState);
    const [submitted, setSubmitted] = useState(false);

    const handleInputChange = event => {
        const { name, value } = event.target;
        setTask({ ...task, [name]: value });
    };

    const saveTask = () => {
        var data = {
            title: task.title,
            description: task.description,
            startDate: task.startDate
        };

        TaskDataService.create(data)
            .then(response => {
                setTask({
                    id: response.data.id,
                    title: response.data.title,
                    description: response.data.description,
                    completed: response.data.completed,
                    startDate: response.data.startDate
                });
                setSubmitted(true);
                console.log(response.data);
            })
            .catch(e => {
                console.log(e);
            });
    };

    const newTask = () => {
        setTask(initialTaskState);
        setSubmitted(false);
    };

    return (
        <FadeIn>
            <div className="submit-form">
                {submitted ? (
                    <div>
                        <h4>Task submitted successfully!</h4>
                        <button className="btn btn-success" onClick={newTask}>
                                Add
                        </button>

                    </div>
                ) : (
                    <div>
                        <div className="form-group">
                            <label htmlFor="title">Title</label>
                            <input
                                type="text"
                                className="form-control"
                                id="title"
                                required
                                value={task.title}
                                onChange={handleInputChange}
                                name="title"
                            />
                        </div>

                        <div className="form-group">
                            <label htmlFor="description">Description</label>
                            <input
                                type="text"
                                className="form-control"
                                id="description"
                                required
                                value={task.description}
                                onChange={handleInputChange}
                                name="description"
                            />
                        </div>

                        <div className="form-group">
                            <label htmlFor="startDate">Start Date</label>
                            <DatePicker
                                selected={ task.startDate }
                                onChange={date => handleInputChange({target: {value: date.toISOString().split("T")[0], name: 'startDate'}})}
                                name="startDate"
                                dateFormat="yyyy-MM-dd"
                            />
                        </div>

                        <button onClick={saveTask} className="btn btn-success">
                            Submit
                        </button>
                    </div>
                )}
            </div>
        </FadeIn>
    );
}

export default AddTask;

When I try to select a date from the Datepicker calendar, app rendering crashes. There are a few errors but it looks like the main one is "Uncaught RangeError: Invalid time value". However, the task is successfully added to the database and I can view it upon reloading the app. But for whatever case, it crashes upon submit.

In contrast, this is my standalone Task component which also contains code for editing an existing task. In that component, everything works 100%. I can open the Datepicker calendar on the selected task, select a new date, and submit it succesfully with zero problems:

import React, { useState, useEffect } from "react";
import { useParams, useNavigate } from "react-router-dom";
import TaskDataService from "../services/task.service";
import DatePicker from 'react-datepicker';
import FadeIn from 'react-fade-in';

const Task = props => {
    const { id } = useParams();
    let navigate = useNavigate();

    const initialTaskState = {
        id: null,
        title: "",
        description: "",
        completed: false,
        startDate: new Date(),
    };
    const [currentTask, setCurrentTask] = useState(initialTaskState);
    const [message, setMessage] = useState("");

    const getTask = id => {
        TaskDataService.get(id)
            .then(response => {
                setCurrentTask(response.data);
                console.log(response.data);
            })
            .catch(e => {
                console.log(e);
            });
    };

    useEffect(() => {
        if (id)
            getTask(id);
    }, [id]);

    const handleInputChange = event => {
        const { name ,value } = event.target;
        setCurrentTask({ ...currentTask, [name]: value });
    };

    const updateCompleted = status => {
        var data = {
            id: currentTask.id,
            title: currentTask.title,
            description: currentTask.description,
            completed: currentTask.completed,
            startDate: currentTask.startDate
        };

        TaskDataService.update(currentTask.id, data)
            .then(response => {
                setCurrentTask({ ...currentTask, completed: status });
                console.log(response.data);
            })
            .catch(e => {
                console.log(e);
            });
    };

    const updateTask = () => {
        TaskDataService.update(currentTask.id, currentTask)
            .then(response => {
                console.log(response.data);
                setMessage("The task was updated successfully!");
            })
            .catch(e => {
                console.log(e);
            });
    };

    const deleteTask = () => {
        TaskDataService.remove(currentTask.id)
            .then(response => {
                console.log(response.data);
                navigate("/tasks");
            })
            .catch(e => {
                console.log(e);
            });
    };

    return (
        <FadeIn>
            <div>
                {currentTask ? (
                    <div className="edit-form">
                        <h4>Task</h4>
                        <form>
                            <div className="form-group">
                                <label htmlFor="title">Title</label>
                                <input
                                    type="text"
                                    className="form-control"
                                    id="title"
                                    value={currentTask.title}
                                    onChange={handleInputChange}
                                />
                            </div>
                            <div className="form-group">
                                <label htmlFor="description">Description</label>
                                <input
                                    type="text"
                                    className="form-control"
                                    id="description"
                                    value={currentTask.description}
                                    onChange={handleInputChange}
                                />
                            </div>

                            <div className="form-group">
                                <label>
                                    <strong>Status:</strong>
                                </label>
                                {currentTask.completed ? "Completed" : "Pending"}
                            </div>

                            <div className="form-group">
                                <label htmlFor="startDate">Start Date</label>
                                <DatePicker
                                    onChange={date => handleInputChange({target: {value: date.toISOString().split("T")[0], name: 'startDate'}})}
                                    name="startDate"
                                    dateFormat="yyyy-MM-dd"
                                    value={currentTask.startDate.toString().split("T")[0]}
                                />
                            </div>
                        </form>

                        {currentTask.completed ? (
                            <button
                                className="badge badge-primary mr-2"
                                onClick={() => updateCompleted(false)}
                            >
                                Mark Pending
                            </button>
                        ) : (
                            <button
                                className="badge badge-primary mr-2"
                                onClick={() => updateCompleted(true)}
                            >
                                Mark Complete
                            </button>
                        )}

                        <button
                            className="badge badge-danger mr-2"
                            onClick={deleteTask}
                        >
                            Delete
                        </button>

                        <button
                            type="submit"
                            className="badge badge-success"
                            onClick={updateTask}
                        >
                            Update
                        </button>
                        <p>{message}</p>
                    </div>
                ) : (
                    <div>
                        <br />
                        <p>Please click on a Task...</p>
                    </div>
                )}
            </div>
        </FadeIn>
    );
}

export default Task;

Done a lot of testing and research but no dice. Any ideas?

1 Answers

Commenter Konrad Linkowski provided the clue to the solution. I removed the line "startDate: response.data.startDate" and now it all works. I do not fully understand, so if anyone wants to explain the answer then please feel free.

Related