Error in creating Rest api in Javascript

Asked

Viewed 227 times

2

The error that is returning is C:\Users\Eric Vitta\Documents\documentos cursos\javascript\src>node index.js TypeError: Cannot read property 'map' of undefined at router.post (C:\Users\Eric Vitta\Documents\documentos cursos\javascript\src\app\controller\projectController.js:37:31) at process._tickCallback (internal/process/next_tick.js:68:7)

I am creating an API to test in Jmeter, I am using Insomnia to test and pass information to the register.

This is the github link with all the code https://github.com/ericvitta/apiteste

It is an API to test REST methods, only for the purpose of study and language improvement. I don’t know why it isn’t returning values in the req.body command because I pass the information in JSON format. Erro que aparece quando testo no Insomnia

const mongoose = require('../../database');
const bcrypt = require('bcryptjs');

const ProjectSchema = new mongoose.Schema({
  title: {
    type: String,
    require: true,
  },
  description: {
    type: String,
    require: true,
  },
  user: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'User',
    require: true,
  },
  tasks: [{
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Task',
  }],
  createdAt: {
    type: Date,
    default: Date.now,
  },
});

const Project = mongoose.model('Project', ProjectSchema);

module.exports = Project;

const mongoose = require('../../database');
const bcrypt = require('bcryptjs');

const TaskSchema = new mongoose.Schema({
  title: {
    type: String,
    require: true,
  },
  project: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Project',
    require: true,
  },
  assignedTo: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'User',
    require: true,
  },
  completed: {
    type: Boolean,
    require: true,
    default: false,
  },
  createdAt: {
    type: Date,
    default: Date.now,
  },
});

const Task = mongoose.model('Task', TaskSchema);

module.exports = Task;

const express = require ('express');
const authMiddleware = require('../middlewares/auth');

const Project = require('../models/Project');
const Task = require('../models/Task');

const router = express.Router();

router.use(authMiddleware);

router.get('/', async (_req, res) => {
   try {
       const projects = await Project.find().populate(['user', 'tasks']);
       return res.send({ projects});

   }catch (err) {
       return res.status(400).send({ error: 'Erro ao carregar projetos.'});
   }
});

router.get('/:projectId', async (req, res) => {
    try {
        const project = await Project.findById(req.params.projectId).populate(['user', 'tasks']);
        return res.send({ project});
 
    }catch (err) {
        return res.status(400).send({ error: 'Erro ao carregar projetos.'});
    }
});

router.post('/', async (req, res) => {
    try {
        const { title, description, tasks } = req.body;

        const project = await Project.create({ title, description, user: req.userId });
      
      await Promise.all(tasks.map(async task => {

          const projectTask = new Task({...task, project: project._id}); 

          await projectTask.save();

         project.tasks.push(projectTask);
    }));
        
        await project.save();  

      return res.send({ project });
    } catch (err) {
        console.log(err);
      return res.status(400).send({ error: 'Erro ao criar novo projeto.' });
    }
});

router.put('/:projectId', async (req, res) => {
    try {
        const { title, description, tasks } = req.body;

        const project = await Project.findByIdAndUpdate(req.params.projectId , {
            title,
            description
        }, {new: true});

        project.tasks = [];
        
        await Task.remove({ project: project._id});
      
      await Promise.all(tasks.map(async task => {

          const projectTask = new Task({...task, project: project._id}); 

          await projectTask.save();

         project.tasks.push(projectTask);
         console.log({ tasks });
    }));
        
        await project.save();  

      return res.send({ project });
    } catch (err) {
        console.log(err);
      return res.status(400).send({ error: 'Erro ao criar novo projeto.' });
    }
});

router.delete('/:projectId', async (req, res) => {
    try {
        await Project.findByIdAndRemove(req.params.projectId);
        return res.send({ Message:'Projeto removido com sucesso.'});
 
    }catch (err) {
        return res.status(400).send({ error: 'Erro ao deletar projeto.'});
    }
});



module.exports = app => app.use('/projects', router);

2 answers

1


Friend, change in INSONIA your http request the key "tasks" to "tasks" as this in your code. (as mentioned by friend Christian Luã Lemos)

 const { title, description, tasks } = req.body;

Other than that, I noticed that you use the following code:

app.use(bodyParser.urlencoded({ extended: false}));

Change to:

app.use(bodyParser.urlencoded({ extended: true}));

This is because with the true option it will make body-parser use the library Qs, this library can work with nested Objects. I talked about her in this other link: What Expressjs urlencoded means in practice?

  • I made the changes but the error still happens

  • The mistake Cannot read property 'map' of undefined of course, it does not find the map method because the variable that is trying to use it is Undefined. I copied your project from github and it works, just match the names according to your code. If you tell the program 'const { title, Description, tasks } = req.body;' it expects the title, Description and tasks tags to be in the request body. Review your insomnia request again and compare if the names are exactly the same as your code. This error you reported in the question is exactly that. Confirm that you are not giving another error now.

  • Thank you so much for the help and attention, I downloaded the project into a friend’s machine and it worked...

  • I’m glad it worked out! a hint, don’t forget to mark Extended as true as I said there in my reply, this will make you can work with nested objects, which is important as you are working with JSON, otherwise if you respond with a nesting JSON it will not come out. If the answer helped you in any way, mark it as right to help other people.

0

You’re picking up the attributes title, description and tasks of the object req.body in this line:

const { title, description, tasks } = req.body;

The error that is occurring in the project is indicating that the variable tasks is undefined, that is, there is no req.body.tasks.

This effect can be observed in the code below:

let obj = {title : "foo", description : "bar"}
let {title, description, tasks} = obj

console.log(title) //foo
console.log(description) //bar
console.log(tasks) //undefined

  • I imagined this but in the creation part of the Schema of Mongo I put tasks and already checked the name several times but I could not understand why it is not bringing the data

  • Checks whether your HTTP request has the tasks parameter.

  • I checked and in the image I had changed the name of the parameter to task to see if it was a conflict with the name but the error remains the same, I tried to put a console.log to return the value but does not return anything

  • I was going to try to use an http client like Postman (https://www.getpostman.com), manually creating a POST request with the title, Description and tasks parameters.

  • This login I’m using does the same process, you create your request , in the format you need and pass the localhost + port you set in the code and you do this test process, I made another user registration and it worked , recorded in the bank and everything but that part of the project and the tasks is with that problem

Browser other questions tagged

You are not signed in. Login or sign up in order to post.