0

I'm building a fullstack React + NodeJS to-do list app following a tutorial. I've created a React Task component that displays info for a particular task and provides update/delete buttons. For some reason, my React updateTask and deleteTask functions update/delete the oldest task regardless of which task I've selected to change.

I'm using the update state variable in React to toggle the update form. Also, logging res in the updateTask function returns success and the correct id to update. However, this is not the id that actually gets updated.

React Task component (Task.js):

import React, { Component } from "react";
import axios from "axios";

class Task extends Component {

    constructor({_id, title, due, desc}) {
        super();
        this.state = {
            id: _id,
            title: title,
            due: due,
            desc: desc,
            update: false
        }
        this.updateTask = this.updateTask.bind(this);
        this.deleteTask = this.deleteTask.bind(this);
    }

    updateTask = () => {
        const {id, title, due, desc} = this.state;
        axios.post("/tasks/update", {
            id: id,
            update: {
                title: title,
                due: due,
                desc: desc
            }
        })
        .then(
            res => {
                console.log(res);
                console.log(res.data);
            }
        );
    };

    deleteTask = () => {
        const {id} = this.state;
        axios.delete("/tasks/delete", {
             id: id
        });
    };

    render() {
        const {id, title, due, desc, update} = this.state;
        return (
            <div className="task">
                <div>{id}</div>
                {update ? 
                <div className="task-update">
                    <input
                        type="text"
                        onChange={e => this.setState({ title: e.target.value })}
                        value={title}
                    />
                    <input
                        type="date"
                        onChange={e => this.setState({ due: e.target.value })}
                        value={!due ? "" : due.slice(0,10)}
                    />
                    <textarea
                        onChange={e => this.setState({ desc: e.target.value })}
                        value={!desc ? "" : desc}
                    />
                    <button onClick={this.updateTask}>
                        Update Task
                    </button>
                </div> 
                : 
                <div className="task-show">
                    <div className="task-info">
                        <div>{title}</div>
                        <div>{!due ? "no date" : due.slice(0,10)}</div>
                        <p>{desc}</p>
                    </div>
                    <div className="task-btns">
                        <button 
                            className="task-edit"
                            onClick={e => this.setState({update: true})}
                        >
                        </button>
                        <button 
                            className="task-done"
                            onClick={() => this.doneTask()}
                        ></button>
                        <button 
                            className="task-del"
                            onClick={this.deleteTask}
                        >
                        </button>
                    </div>
                </div>
                }
            </div>
        );
    }

}

export default Task;

NodeJS task controller:

var express = require('express');
var router = express.Router();
const Task = require("../models/task");
const Data = require("../models/data");

router.get("/all", (req, res) => {
  Task.find((err, tasks) => {
    if (err) return res.json({ success: false, error: err });
    return res.json({ success: true, tasks: tasks });
  });
});

router.post("/update", (req, res) => {
  const { id, update } = req.body;
  Task.findOneAndUpdate(id, update, err => {
    if (err) return res.json({ success: false, error: err });
    return res.json({ success: true, id: id});
  });
});

router.delete("/delete", (req, res) => {
  const { id } = req.body;
  Task.findOneAndDelete(id, err => {
    if (err) return res.send(err);
    return res.json({ success: true });
  });
});

router.post("/create", (req, res) => {
  let task = new Task();

  const {title, due, desc} = req.body;

  if (!title) {
    return res.json({
      success: false,
      error: "INVALID INPUTS"
    });
  }

  task.title = title;
  task.due = due;
  task.desc = desc;

  task.save(err => {
    if (err) return res.json({ success: false, error: err });
    return res.json({ success: true });
  });
});

module.exports = router;

Thank you for the help in advance!

2
  • What do you mean by wrong record. Which record is being updated/deleted instead? Commented Jan 21, 2019 at 17:46
  • @PrakashSharma Hi Prakash! I apologize if I wasn't clear - I'm struggling to articulate my problem. For example, I'm trying to delete a Task with the mongoDB _id 5c456a1261bc20082ff86977 however, 5c456a1261bc20082ff86974 will be deleted instead (assuming this is the oldest Task _id). Commented Jan 21, 2019 at 17:49

2 Answers 2

1

You should use Task.findOneAndUpdate({_id: id}, ...). If you don't use valid query like {_id: id}, it always returns the first object as far as I know.

Mogoose findOneAndUpdate accepts query as first parameter.More info here.

Sign up to request clarification or add additional context in comments.

Comments

0

Try to update this.state.id onclick of delete task or pass in e.target.value to delete function and then pick the Id to the api call

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.