Home > database >  node Js : API post 400 bad request
node Js : API post 400 bad request

Time:12-13

this is my first project in node js and i created an API that have get, delete, update, and post. i tested GET and response 200 ok but POST is 400 bad request i don't know why ... i tested this in postman and vue js too but same result

below is my code in nodeJs: can someone please tell me what is the problem?

thanks in advance

//question.js

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const questionSchema = new Schema({
  questionTitle: {
    type: String,
    required: true,
  },
  is_solver_selected : {
    type: Boolean,
    default : false,
  },
  reviewed: {
    type: Boolean,
    default : false,
  },
  question_file_path: {
    type: String,
    required: true
  },
  description : {
    type : String,
    required : true
  },
  solutions : [
    {
      type: Schema.Types.ObjectId,
      ref:"Solution",
      default : []
    }
  ],
  owner : {
    type : Schema.Types.ObjectId,
    ref : "User",
    required : true
  },
  categories : [{
    type : Schema.Types.ObjectId,
    ref : "Category",
    required : true
  }],
  answered: {
    type: Boolean,
    default : false,
  },
  budget : {
    type : String,
    required : true
  }
}, { timestamps: true });

const Question = mongoose.model('Question', questionSchema);
module.exports = Question;

//questionApiController

const Category = require('../models/category');
const Question = require('../models/question');
const User = require('../models/user');
const  validators  = require('../validators');

let questionApiController = {

    
  // Get a single question

  get_question : async (req , res) => {
    const id = req.params.id;

    try {
        const question = await Question.findById(id,(err, question) => {
          
          if (err) return res.status(400).json({response : err});
          
          res.status(200).json({response : question})
      }).populate('owner', 'username').populate('categories').populate({
        path : "solutions",
        populate : {path : "solver_candidate" , select : "username"}});
  
    } catch (err) {
        res.status(400).json(err);
    }
  },

  // Get all the questions

  get_questions: async (req , res) => {
    try {
      const questions = await Question.find((err, questions) => {
          
        if (err) return res.status(400).json({response : err});
        
        res.status(200).json({response : questions})
        
    }).sort({ createdAt: -1 }).populate('owner', 'username').populate('categories').populate({
      path : "solutions",
      populate : {path : "solver_candidate" , select : "username"}});
    } catch (err) {
        res.status(400).json(err);
    }
  },

  // Create a question
  
  create_question : async (req , res) => {

    const {error} = validators.postQuestionValidation(req.body);
    if(error) return res.status(400).json({ "response" : error.details[0].message})

    try {
      const question = await new Question(req.body);

      
      
      
      User.findByIdAndUpdate(req.body.owner)
      .then(result => {
        result.questions.push(question._id)
        result.save((err, categories) => {
          
          if (err) return res.status(400).json({response : {error : err , explanation : " Error binding to the user !"}});
          
      });

      })
      .catch(err => {
      
      res.status(400).json({response: err });
    });


    req.body.categories.forEach(element => {
      Category.findById(element).then(result => {
        
      }).catch(err => {
        res.status(400).json({response : err });
      })
    })



    question.save((err, question) => {
          
      if (err) return res.status(400).json({response : err});
      
      res.status(200).json({response : " Question created Successfully"})
      
  });

    } catch (err) {
        res.status(400).json(err);
    }
  },

  // Delete question

  delete_question : async (req , res) => {

    const id = req.params.id;

    var questionExist = false;
    var userId ;

    const question = await Question.findById(id).then(result => {
      questionExist = true;
      userId = result.owner;
    }).catch(err => {
      questionExist = false;
      res.status(400).json({response : err });
    });

    

    if(questionExist){
      try {
        Question.findByIdAndRemove(id ,(err, question) => {
          // As always, handle any potential errors:
          if (err) return res.json({response : err});
          // We'll create a simple object to send back with a message and the id of the document that was removed
          // You can really do this however you want, though.
          const response = {
              message: "Question successfully deleted",
              id: question._id
          };
          return res.status(200).json({response : response });
      });
  
        User.findByIdAndUpdate(userId)
          .then(result => {
            
            let pos = result.questions.indexOf(question._id);
            result.questions.splice(pos,1);
            result.save((err, categories) => {
            
              if (err) return res.status(400).json({response : {error : err , explanation : "Error binding unbinding from the user"}});
              
          });
  
          })
          .catch(err => {
          
          res.json({response: err });
        });
  
      } catch (err) {
          res.status(400).json(err);
      }
    }

    else {

      return res.status(400).send( { "response" : "A question with that id was not find."});
    }    

  },

  // Update question

  update_question : async (req , res) => {
    const id = req.params.id;
    Question.findByIdAndUpdate(id,req.body,
      function(err, result) {
          if (err) {
            res.status(400).json({response : err});
          } else {
            res.status(200).json({response : "Question Updated"}); 
            console.log(result);
          }
        })
  },

  bind_question_to_solver : async (req , res) => {
    const id = req.params.id;
    Question.findByIdAndUpdate(id,{
        solver : req.body.solver ,
        response_file_path : req.body.response_file_path},function(err, result) {
          if (err) {
            res.status(400).json({response : err});
          } else {
            res.status(200).json({response : "Question Bind to Solver"});
            //Update the user solver by adding the question id in its quesion array1  
            console.log(result);
          }
        })
  },

  // Get question's questions

  get_question_categories : async (req , res) => {

    const id = req.params.id;
    try {
      const question_categories = await Question.findById(id).populate("categories")
      console.log(question_categories)
      res.json(question_categories)
    } catch (err) {
      console.log(err);
        res.json(err);
    }
  }


}


module.exports = questionApiController

//question controller 

const Question = require('../models/question');

const question_index = (req, res) => {
  Question.find().sort({ createdAt: -1 })
    .then(result => {
      res.render('index', { questions: result, title: 'All questions' });
    })
    .catch(err => {
      console.log(err);
    });
}

const question_details = (req, res) => {
  const id = req.params.id;
  Question.findById(id)
    .then(result => {
      res.render('details', { question: result, title: 'Question Details' });
    })
    .catch(err => {
      console.log(err);
      res.render('404', { title: 'Question not found' });
    });
}

const question_create_get = (req, res) => {
  res.render('create', { title: 'Create a new question' });
}

const question_create_post = (req, res) => {
  const question = new Question(req.body);
  question.save()
    .then(result => {
      res.redirect('/questions');
    })
    .catch(err => {
      console.log(err);
    });
}

const question_delete = (req, res) => {
  const id = req.params.id;
  Question.findByIdAndDelete(id)
    .then(result => {
      res.json({ redirect: '/questions' });
    })
    .catch(err => {
      console.log(err);
    });
}

module.exports = {
  question_index, 
  question_details, 
  question_create_get, 
  question_create_post, 
  question_delete
}

sent request:

Post http://localhost:9000/questions/api/add content-type: application/json

{ "description": "d", "questionTitle": "ddd", "categories":"ddd", "question_file_path":"d.pdf", "budget":"d", "owner":"bla",

}

`error message': HTTP/1.1 400 Bad Request
SyntaxError: Unexpected token } in JSON at position 160 at JSON.parse () at parse (C:\Users\saad\Desktop\APi-master-nodejs\node_modules\body-parser\lib\types\json.js:89:19) at C:\Users\saad\Desktop\APi-master-nodejs\node_modules\body-parser\lib\read.js:121:18 at invokeCallback (C:\Users\saad\Desktop\APi-master-nodejs\node_modules\raw-body\index.js:224:16) at done (C:\Users\saad\Desktop\APi-master-nodejs\node_modules\raw-body\index.js:213:7) at IncomingMessage.onEnd (C:\Users\saad\Desktop\APi-master-nodejs\node_modules\raw-body\index.js:273:7) at IncomingMessage.emit (events.js:327:22) at endReadableNT (_stream_readable.js:1327:12) at processTicksAndRejections (internal/process/task_queues.js:80:21)

CodePudding user response:

based on your updated post, i would start to fix the provided json. because as the response says, it is invalid. JSON does not have trailing comma at the end of the last entry.

{ "description": "d", "questionTitle": "ddd", "categories":"ddd", "question_file_path":"d.pdf", "budget":"d", "owner":"bla"}

would be fine.

CodePudding user response:

Check why-body-parser-json-is-not-working-showing-syntaxerror-unexpected-token post, you have a similar problem.

You are sending , symbol after last field in the json object which is not expected by the body-parser when you are sending content-type: application/json

  • Related