express create standard JSON return format - javascript

I'm new to express, currently if I want to send a response I would do the following
//...
res.json({
status: 200,
message: "success",
data: "something"
})
//...
for all my controllers functions I would do it this way. I guess this is kind of overwhelming so I was thinking if it's possible to make a generalized version of response.
so after some search I found there is 2 ways of achieving this:
1. use a middleware that runs at the end of each route
I found this answer. which made it clear but I think it's a waste of time and my controller then won't be readable enough and I must do the following in every controller function
req.responseObject = response;
return next()
2. override response class of the express itself
this is much promising, but unfortunately after so many tries and following express docs I couldn't get it to work
here is what I've tried so far
I've created this util function here:
//myRes.js
module.exports = function (code, message, payload) {
return this.status(code).json({
status: 'success', // this will be variable according to whatever code I get
code: code,
message: message || '',
payload: payload || '',
});
};
then I've added this line to app.js
// app.js
const express = require('express');
const app = express();
const myRes= require('./utils/myRes');
app.response.send = myRes;
//...
and this is how I use it on my controller
res.send(200, "hello world", [{"key": "value"}])
when I try to run this I got this Error stack
RangeError: Maximum call stack size exceeded
at JSON.stringify (<anonymous>)
at stringify ([project_dir]\node_modules\express\lib\response.js:1123:12)
at ServerResponse.json ([project_dir]\node_modules\express\lib\response.js:260:14)
at ServerResponse.module.exports [as send] ([project_dir]\src\utils\response.js:2:28)
at ServerResponse.json ([project_dir]\node_modules\express\lib\response.js:267:15)
at ServerResponse.module.exports [as send] ([project_dir]\src\utils\response.js:2:28)
at ServerResponse.json ([project_dir]\node_modules\express\lib\response.js:267:15)
at ServerResponse.module.exports [as send] ([project_dir]\src\utils\response.js:2:28)
at ServerResponse.json ([project_dir]\node_modules\express\lib\response.js:267:15)
at ServerResponse.module.exports [as send] ([project_dir]\src\utils\response.js:2:28)
at ServerResponse.json ([project_dir]\node_modules\express\lib\response.js:267:15)
at ServerResponse.module.exports [as send] ([project_dir]\src\utils\response.js:2:28)
at ServerResponse.json ([project_dir]\node_modules\express\lib\response.js:267:15)
at ServerResponse.module.exports [as send] ([project_dir]\src\utils\response.js:2:28)
at ServerResponse.json ([project_dir]\node_modules\express\lib\response.js:267:15)
at ServerResponse.module.exports [as send] ([project_dir]\src\utils\response.js:2:28)
why JSON.stringify is complaining I haven't used this function on my entire application
also I am not just capped to these 2 solutions you can suggest other ways if you think it's better

clarifying what #Ariel said in the comments
Express response calls send internally refer to this function from express at lines [120, 123, 136] and that was causing a infinite loop that's why it was saying
Maximum call stack size exceeded
so all I needed to do is to change my function name from send to maybe "sends" and that just worked
it was a bad idea trying to overwrite the built in send function

Related

Error while connecting to local Redis server in Node.js

I have Redis server running on localhost at port 6379 and I'm connecting to it like that:
const redisClient = redis.createClient({
url: `redis://localhost:6379`,
legacyMode: false
});
Although when I try to connect to it, it gives the following error:
TypeError [ERR_INVALID_ARG_TYPE]: The "chunk" argument must be of type string or an instance of Buffer or Uint8Array. Received undefined
at new NodeError (node:internal/errors:371:5)
at _write (node:internal/streams/writable:312:13)
at WriteStream.Writable.write (node:internal/streams/writable:334:10)
at Commander.<anonymous> (C:\Users\atsukoro\Desktop\Projekty\simpleanilist\src\index.ts:42:24)
at Commander.emit (node:events:526:28)
at Commander.emit (node:domain:475:12)
at RedisSocket.<anonymous> (C:\Users\atsukoro\Desktop\Projekty\simpleanilist\node_modules\#redis\client\dist\lib\client\index.js:347:35)
at RedisSocket.emit (node:events:526:28)
at RedisSocket.emit (node:domain:475:12)
at RedisSocket._RedisSocket_connect (C:\Users\atsukoro\Desktop\Projekty\simpleanilist\node_modules\#redis\client\dist\lib\client\socket.js:114:14) {
code: 'ERR_INVALID_ARG_TYPE'
}
I found that legacyMode false will fix that issue but that didn't work either.

Node.js changing type of variable from Object to Undefined

I am trying to make API call from Node.js Expressjs. API call is working fine however after parsing the response to JSON, when I try to access different fields it gives me an error.
I try to log the type of one element of the JSON object to console. First it says Object and then it says undefines (or if try to log the content itself, it gives me an error).
var request = require('request');
const app = express();
//For serving static pages
// app.use(express.static('./static'))
app.get('/', (req, res) =>{
res.send('You have successfully contacted the API')
});
app.get('/:ticker', (req, res) => {
var requestOptions = {
'url': 'https://api.tiingo.com/tiingo/daily/' + req.params.ticker + '/prices?startDate=2019-01-02&token=74e7c9d22c2ffe8e9b5643edc2ef48bbddc6e69e',
'headers': {
'Content-Type': 'application/json'
}
};
request(requestOptions,
function(error, response, body) {
result = JSON.parse(body);
console.log('The type is ' + typeof (result[0].date)) //This statement prints different results twice
res.send(result);
}
);
});
app.listen(process.env.PORT || 3000)
Terminal says:
The type is string
D:\Web Dev Bootcamp\NodeJS-Tutorial\index.js:24
console.log('The type is ' + typeof (result[0].date))
^
TypeError: Cannot read property 'date' of undefined
at Request._callback (D:\Web Dev Bootcamp\NodeJS-Tutorial\index.js:24:60)
at Request.self.callback (D:\Web Dev Bootcamp\NodeJS-Tutorial\node_modules\request\request.js:185:22)
at Request.emit (events.js:314:20)
at Request.<anonymous> (D:\Web Dev Bootcamp\NodeJS-Tutorial\node_modules\request\request.js:1154:10)
at Request.emit (events.js:314:20)
at IncomingMessage.<anonymous> (D:\Web Dev Bootcamp\NodeJS-Tutorial\node_modules\request\request.js:1076:12)
at Object.onceWrapper (events.js:420:28)
at IncomingMessage.emit (events.js:326:22)
at endReadableNT (_stream_readable.js:1223:12)
at processTicksAndRejections (internal/process/task_queues.js:84:21) [nodemon] app crashed - waiting for file changes before starting...
Run a quick console.log(result) to make sure that result is being stored as an Array. I suspect that when you are parsing the JSON it is storing result as an object.
Figured out what the issue was. Actually express was making a request for favicon.ico by itself and during that request apparently result variable was undefined. I simply set up another route for handling favicon request as suggested [here][1]. Now the code is simply logging the result once and I am able to access the fields of JSON object properly.
Edit: as pointed out by a contributor, its the browser thats making the favicon request and 'not' the express.
[1]: Node Express "favicon.ico" not found error

getting error in node js "Error: Can't set headers after they are sent."

Say “I'm getting error in node js while probably while login or when code crashes ie, Error: Can't set headers after they are sent?”
err: Error: Can't set headers after they are sent.
at validateHeader (_http_outgoing.js:491:11)
at ServerResponse.setHeader (_http_outgoing.js:498:3)
at basicAuthentication (/home/brainmobi/git/Abhijeet/Node/qarari_backend/lib/middleware/basicAuth.js:16:16)
at Layer.handle [as handle_request] (/home/brainmobi/git/Abhijeet/Node/qarari_backend/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/home/brainmobi/git/Abhijeet/Node/qarari_backend/node_modules/express/lib/router/index.js:317:13)
at /home/brainmobi/git/Abhijeet/Node/qarari_backend/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/home/brainmobi/git/Abhijeet/Node/qarari_backend/node_modules/express/lib/router/index.js:335:12)
In Node.js and almost every server languages, you can not set another header after some headers are already sent in a single response to the client.
For Example, this use case will not work
app.get('/', (err, res) => {
res.send('Hello!'); // This will send a response to the client, along with the appropriate headers.
res.send('How are you?!'); // This will throw the same error as you are getting before a response along with some headers are already sent
})

Node Js mysql(and mysql2) ECONNRESET

i am currently trying to connect to a MySQL server on the internet using Node.Js with the mysql or the mysql2 NPM dependencies to use queries and other related stuff.
the code is simple...
//i import my dependency
const mysql = require('mysql2') //either 'mysql' or 'mysql2'
//i create my pool to create connections as needed
var conn = mysql.createPool({
host: 'some_database_i_have_access_to.mysql.uhserver.com',
user: 'valid_user',
password: 'valid_password',
database: 'some_existing_database'
})
//i try to connect (this is the part where it fails)
conn.getConnection((err,conn) => {
if (err) throw err //<- the error is thrown here
//i do query stuff
conn.query("SELECT * FROM atable",(err,res,firlds) => {
if(err) throw err
console.log(JSON.stringify(res))
})
//i close the connection
conn.end()
})
yet i always get an Error like this:
Error: read ECONNRESET
at TCP.onStreamRead (internal/stream_base_commons.js:111:27)
--------------------
at Protocol._enqueue (C:\Users\Aluno\Desktop\my-project\node_modules\mysql\lib\protocol\Protocol.js:144:48)
at Protocol.handshake (C:\Users\Aluno\Desktop\my-project\node_modules\mysql\lib\protocol\Protocol.js:51:23)
at Connection.connect (C:\Users\Aluno\Desktop\my-project\node_modules\mysql\lib\Connection.js:118:18)
at Object.<anonymous> (C:\Users\Aluno\Desktop\my-project\private\dtp-mysql.js:13:6)
at Module._compile (internal/modules/cjs/loader.js:707:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:718:10)
at Module.load (internal/modules/cjs/loader.js:605:32)
at tryModuleLoad (internal/modules/cjs/loader.js:544:12)
at Function.Module._load (internal/modules/cjs/loader.js:536:3)
at Module.require (internal/modules/cjs/loader.js:643:17)
all i know about the error is that the connection abruptly closes in one of the sides as stated in this question (Node js ECONNRESET), but nothing more, and creating singular connections does not solve this issue for me either.
any fixes to that?
you can also ref below url.
error while inserting LARGE volume data in mysql by using node.js (error code: 'ECONNRESET')
I have fixed this issue. It is caused by the default definition max_allowed_packet. Find max_allowed_packet in my.ini (C:\ProgramData\MySQL\MySQL Server 5.7). Update to 'max_allowed_packet=64M'. Restart mysql. Done.
Hi I know this was asked some time ago, but is it possibly because you're using:
conn.end()
Since you're using a Pooled connection, I think you can release the connection using
conn.release()
Or
conn.destroy()

NodeJS Express Request Entity Too Large

I've tried many solutions listed here (increasing of memory limit, adding parameterlimit, adding type as 'application/json') to fix this 'Request Entity too large' error (it also returns http code 413). But none of them seem to make this error go away.
The current size of the json can range from 200k up to 400k entities.
Here is the current configuration:
app.use( bodyParser.json({limit: "15360mb", type:'application/json'}) );
app.use(bodyParser.urlencoded({
limit: "15360mb",
extended: true,
parameterLimit:5000000,
type:'application/json'
}));
app.use(bodyParser())
Any ideas on how to increase the limit?
More information
This is the full error message if it helps:
{ Error: Request Entity Too Large
at respond (/home/nodejs/server/node_modules/elasticsearch/src/lib/transport.js:307:15)
at checkRespForFailure (/home/nodejs/server/node_modules/elasticsearch/src/lib/transport.js:266:7)
at HttpConnector.<anonymous> (/home/nodejs/server/node_modules/elasticsearch/src/lib/connectors/http.js:159:7)
at IncomingMessage.bound (/home/nodejs/server/node_modules/lodash/dist/lodash.js:729:21)
at emitNone (events.js:111:20)
at IncomingMessage.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1056:12)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickCallback (internal/process/next_tick.js:180:9)
status: 413,
displayName: 'RequestEntityTooLarge',
message: 'Request Entity Too Large',
path: '/_bulk',
query: {},
body: '<large body here>'
}
Solution
The error was indeed due to wrong configuration on elasticsearch and not nodejs. Manage to fix this by following https://github.com/elastic/elasticsearch-js/issues/241 and setting http.max_content_length: 500mb in elasticsearch.yml.
#ryanlutgen also provided a link for more information about this error here.
https://github.com/elastic/elasticsearch/issues/2902
This issue has been fixed. Thanks for all the input!
If You doesn't solve your issue, bodyParser also has a limit.
You must use
app.use(bodyParser({limit: '4MB'}))

Categories

Resources