So I have been given an API to which I need to send a post request to create a task within a list, but when I try to send the request, I get the following error (I am trying it in postman).
The following is the schema of a post request body I need to send to the API, and the image is the request I am sending with the postman (I need to use the x-www-form-urlencoded because otherwise, it is not working)
{
title: { type: String,required:true},
description: String,
done:Boolean,
date: { type: Date, default: Date.now },
list:{
type: Schema.ObjectId,
ref: 'List'
}
So can you please help me with this?
I get the following error.
Cast to ObjectID failed for value \"Daily Tasks\" at path \"list\"
The API is expecting you to pass the id of a List, not its name.
It's probably expecting you to do an other API call before to get that id.
It should look like this: "507f1f77bcf86cd799439011"
Additionally, you can look at the documentation of MongoDB for information about the ObjectId format: https://docs.mongodb.com/manual/reference/method/ObjectId/
Related
I need to retrieve data based on a date. I tested my route with Postman and everything works fine. However, when I do my axios query with a date, it returns an empty array. I understood that it would be a date format problem with axios, but I couldn't solve it. Could you help me please?
Here is my code in the front:
const getDailyWorking =()=>{
let datas={
activity_creationTimestamp: ('2022-06-28'),
user_id:1
}
console.log(datas)
return axios.get(config.api_url+'/dailyWork', datas).then((response)=>{
console.log(response.data)
}).catch((err)=>{
console.log(err)
})
}
You're using the wrong type of request. A GET request can't include a body in the request, while a POST request can include a body in the request. Maybe you should check the documentation again and get the parameters sorted.
You can specify the GET parameters like this axios.get('/path', { params: datas } which is equivalent to axios.get('/path?activity_creationTimestamp=2022-06-28&user_id=1')
. Otherwise, provide more information about the server side route.
I am new to Node.js and i am trying to refresh the data periodically using the below code:
router.post('/getMessage',function(req,res){
setInterval(findMessage,5000);
function findMessage() {
Message.find(
{
$or: [
{sender: req.body.sender, receiver: req.body.receiver},
{sender: req.body.receiver, receiver: req.body.sender}
]
},
(err, data) => {
res.send({success: true, data: data});
}
);
}
});
But this gives an error: "Cannot set headers after they are sent". I understand that res.send calls res.end() implicitly and therefore this error is occuring. And have tried res.write() also. But i am returning an object and not a String or buffer, hence it also failed to work.
It would be great if someone could give an example of how to achieve this exactly.
response.send() method does two task
1. write content on the response and send.
2. End connection with res.end().
So, when you did response.send(), then it sends your message and closes the connection. For that reason, you getting the error "Cannot set headers after they are sent".
So, the conclusion is that you can't send multiple responses using response.send().
You can achieve this by the socket.io or you can make the request from frontend after an interval.
I am building the API with Swagger and NodeJS, the annoying problem I have faced so far is Swagger validates the response, and it's not always smooth.
My case:
In file .yaml: I checked the yaml syntax with Swagger Editor => File Yaml is correct.
/user/createNew:
x-swagger-router-controller: xxxxxxx
post:
tags:
- User
summary: Create New User
# used as the method name of the controller
operationId: createNewUser
parameters:
- name: NewUserReq
in: body
required: true
description: Email register
schema:
$ref: "#/definitions/NewUserReq"
responses:
"201":
description: Successful
schema:
# a pointer to a definition
$ref: "#/definitions/CreateUserResp"
# responses may fall through to errors
default:
description: Error
schema:
$ref: "#/definitions/ErrorResponse"
CreateUserResp:
properties:
status:
type: integer
description: Response status
response:
$ref: "#/definitions/MsgResponse"
MsgResponse:
required:
- resp_msg
properties:
resp_msg:
type: string
To check the response format, I generated the NodeJs file from Swagger Editor
examples['application/json'] = {
"response" : {
"resp_msg" : "aeiou"
},
"status" : 123
};
In controller file .js:
function createNewUser(req,res){
....
var resp = new Object();
resp.resp_msg=data.email;
final_response.status = 200;
final_response.response = resp;
console.log("createNewUser::Query succeffully", JSON.stringify(final_response));
//{"status":200,"response":{"resp_msg":"test#gmail.com"}}
res.set('Content-Type', 'application/json');
res.json(final_response);
}
Try to run API with Postman, the error happens with log below:
Error: Response validation failed: failed schema validation
at throwErrorWithCode (/var/app/current/node_modules/swagger-express-mw/node_modules/swagger-node-runner/node_modules/swagger-tools/lib/validators.js:121:13)
at Object.module.exports.validateAgainstSchema (/var/app/current/node_modules/swagger-express-mw/node_modules/swagger-node-runner/node_modules/swagger-tools/lib/validators.js:176:7)
at /var/app/current/node_modules/swagger-express-mw/node_modules/swagger-node-runner/node_modules/swagger-tools/middleware/swagger-validator.js:141:22
at /var/app/current/node_modules/swagger-express-mw/node_modules/swagger-node-runner/node_modules/swagger-tools/node_modules/async/lib/async.js:356:13
at async.forEachOf.async.eachOf (/var/app/current/node_modules/swagger-express-mw/node_modules/swagger-node-runner/node_modules/swagger-tools/node_modules/async/lib/async.js:233:13)
at _asyncMap (/var/app/current/node_modules/swagger-express-mw/node_modules/swagger-node-runner/node_modules/swagger-tools/node_modules/async/lib/async.js:355:9)
at Object.map (/var/app/current/node_modules/swagger-express-mw/node_modules/swagger-node-runner/node_modules/swagger-tools/node_modules/async/lib/async.js:337:20)
at validateValue (/var/app/current/node_modules/swagger-express-mw/node_modules/swagger-node-runner/node_modules/swagger-tools/middleware/swagger-validator.js:134:11)
at ServerResponse.res.end (/var/app/current/node_modules/swagger-express-mw/node_modules/swagger-node-runner/node_modules/swagger-tools/middleware/swagger-validator.js:252:9)
at ServerResponse.send (/var/app/current/node_modules/express/lib/response.js:205:10)
I cannot figure out what caused the error, I double checked the structure of JSON response.
Very appreciate for any suggestion.
You have put required: true which means you have to pass that parameter otherwise Response Validation Failed will appear.
I tried to reproduce but it gives me some errors. However, I tried removing MsgResponse and defining CreateUserResp as a single definition, and it worked:
CreateUserResp:
type: object
properties:
response:
type: object
properties:
resp_msg:
type: string
description: The response object
status:
type: number
description: The status code
It seems like you're not defining response as an object, and just adding some properties to it.
After trying some experiments, I made it work. My solution simply is changing response code "201" to "200" in yaml file, and it worked. I don't know why I left the response code "201". Anyway, I am still new with this, and don't know if it's a best practice or not. I am open to receive any better suggestion.
You can get this error if you don't specify in the header the data type sent within the request body
Content-Type : application/json
This is what I have:
server.route({
method: 'POST',
path: '/somePath/',
config: {
payload:{
output: 'stream'
}
});
I expect a short XML and that is why I using 'stream' instead of 'data'. I am using FakeToe as the XML parser as it is stream based and in my handler function I call request.payload.pipe(parser). All I want to check is if there is any POST data in the request and if not send a bad request back to the user.
I have thought about getting the size of data in the request.payload stream but there does not seem to be straightforward of doing that without pulling first and then pushing back data into the stream, which I don't like.
Everything works perfectly when the data is there, but if not FakeToe does not call the callback function with an error saying that the stream is empty. Also, I do not want to call request.payload.read method myself just to check if there is any data.
Any way to do that in hapijs?
You can use Joi to validate the presence of a payload. It is a schema and validation module provided by Hapi. It will automatically validate any requests received at an endpoint and reply with an appropriate badRequest message if the validation fails.
var Joi = require('Joi');
server.route({
method: 'POST',
path: '/somePath/',
config: {
payload:{
output: 'stream'
}
validate: {
payload: Joi.any().required()
}
});
More about this here and here.
EDIT:
As per the discussion in this GitHub Issue, a validation object like
Joi.object({
pipe: Joi.func().required()
}).unknown();
Can be used to test whether the payload is actually a stream.
I suppose that you have content-length header ? You could check that from request.headers instead of reading the payload.
My app is Node.js using Express.
Sending this test data from my client using jQuery POST:
{
title: 'hello',
notes: [
{title: 'note 1'},
{title: 'note 2'}
]
}
And this is the result in my server code:
{ title: 'hello', notes: { '0': { title: 'note 1' }, '1': { title: 'note 2' } } }
I want to get the array of notes to insert into my DB as an Array. What am I missing?
As I can't add an answer myself for 8 hours (wtf?) BUT it does not really answer why Express.bodyParser does not parse JSON correctly
Ok I can get it to work by using:
JSON.stringify ( data )
on the client then server side using
JSON.parse( req.rawBody )
This does feel wrong and why does Express.bodyParser not parse JSON correctly?!
On your client:
$.ajax({
type: 'POST',
data: JSON.stringify(data),
contentType: 'application/json',
url: '/endpoint'
});
On your server:
console.log('POST: ',req.body);
The problem is jQuery mucks around with your data before sending it. If you set the right MIME type, than it leaves you free.
Can you post your client side jQuery code, please? By default jQuery will send data as urlencoded, not JSON. See this question's answer for the way to ensure jQuery sends real JSON data.
FYI the express/connect bodyParser middleware simply uses JSON.parse to parse JSON (and qs.parse to parse urlencoded data). I don't think there are any glaring bugs in those code. Thus I think you should double-check the data you are sending from the browser.
I came across this old question when looking for some other nodejs stuff.
It is a common misconception that jQuery.ajax() functions send data using JSON. Data is sent by jQuery as POST data and not a JSON string. As such all data types (including the numbers in your array) are sent as strings.
This means that express parses the 'array' keys as a string, and since an array can't have a string key in javascript without being an object, it is cast to an object.
It all makes sense then; you can use Express.bodyParser to get a result like that, or you can use JSON.parse or even eval('(' + myPostedData + ')') to get a result object without the indexes.
With your current setup, all you need to do is:
for(var j = 0; j < myVariable.notes.length; j++)
{
var currentNode = myVariable.notes[j];
//currentode.title should be 'note 1' for j = 0, etc
}