Node Express, function with parameters inside res.send - node.js

Im trying to return a value depending a parameter received. But im getting:
TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received type function ([Function])
app.get('/api/:producto', (req, res) => {
const strProd = req.params.producto;
res.send( (strProd) => {
if (strProd==1) {
return "1"
} else {
return "2"
}
})
})
Thanks in advance!

As the error message says. The arguement of res.send function must be a string, buffer, array, etc. You're passing a function into the send function.
So simply put the if checks first and then give the appropriate response.
app.get('/api/:producto', (req, res) => {
const strProd = req.params.producto;
if (strProd === "1") {
return res.send("1")
} else {
return res.send("2")
}
})

Related

To support function calls through POST API body

{
"expression":"uniqueCount('apple','grape',pickRandom('Harsha', 'Deva'))"
}
I am trying to parse this expression through a REST API function.
const functions = {
//returns the uniquecount of any element
uniqueCount: (...args) => {
return new Set(args).size;
},
ksmallest: (k, ...args) => {
//returns the kth smallest lexicographic order
console.log(k);
return [parseInt(k) - args.sort()];
},
pickRandom: (...args) => {
//picks any random element from the array
return args[Math.floor(Math.random() * args.length)];
},
};
but I am getting this error when I am testing it on ThunderClient/Postman:
{
"error": "Invalid string length"
}
While only one function works but when we call one function inside another function's parameter, it gives that error.
Expected result:
uniqueCount('apple', 'grape', pickRandom('Harsha', 'Deva'))
value of the expression is 3your text

Type '(err: any) => void' has no properties in common with type 'QueryOptions' on Node route

I have the following route in a Node controller that is giving me an error that prevents Node from running
public async deletePost(req: Request, res: Response) {
const { id } = req.params;
const deletedPost = await BlogPostModel.findByIdAndDelete(id, err => {
if (err) {
res.status(400).send.send('Error deleting post');
}
});
// needs to send error if post not found (400 status code)
res.status(200).send(deletedPost);
}
I get an error for the err => { section of my code saying:
Type '(err: any) => void' has no properties in common with type 'QueryOptions'
I don't fully understand this error, but it sounds like its requiring I type out the argument in the error handling callback function. However, I've also tried (err:any)=> and that doesn't work as well. Would anyone be able to fill me in on how to correctly use a callback function for error handling here?
Seems like the second argument must be of type QueryOptions, but you pass a function instead
It's not how you should handle errors, you can't mix promises and callbacks
public async deletePost(req: Request, res: Response) {
const { id } = req.params;
try {
const deletedPost = await BlogPostModel.findByIdAndDelete(id);
} catch (err) {
return res.status(400).send.send("Error deleting post");
}
res.status(200).send(deletedPost);
}

Fastify error handler returns wrong error if I call reply.code() before returning the error object

I have an async error handler that looks like this
export default async function processError(
err: FastifyError,
req: FastifyRequest,
res: FastifyReply
): Promise<FastifyError | TErrorReply> {
console.log({ err: err.stack });
let processedError: TErrorReply = err;
if (isDatabaseError(err))
processedError = processDatabaseError(req, res, err);
if (isSchemaValidationError(err))
processedError = processSchemaValidationError(req, res, err);
if (process.env.NODE_ENV === 'development')
processedError = {
...processedError,
stack: err.stack || new Error().stack,
};
console.log({ processedError });
res.code(Number(err?.code || err?.statusCode || 500));
return processedError;
}
I then use it like this
fastify.setErrorHandler(processError);
Inside processSomethingError functions I set a specific code and return a specific error, here is an example.
function processDatabaseError(
req: FastifyRequest,
res: FastifyReply,
err: DatabaseError
): TErrorReply {
const t = getFixedT('en', 'errors');
switch (err.code) {
case '23505': {
const match = err.detail?.match(/\((.+?)\)/);
if (match) {
const key = match[1];
res.code(409);
return {
fields: { [key]: 'duplicated' },
};
}
}
}
res.code(400);
return {
message: t<string, TTranslationKeys['errors']>('fallback'),
};
}
My problem is that if I have
res.code(Number(err?.code || err?.statusCode || 500));
inside processError, just before returning the processedError, it ignores the processedError and instead sends the original error, which is represented by the err argument inside processError function.
If I remove the res.code.. - everything works fine and the actual processedError is returned.
Why is it working like this?
I just want to set the code or the error I want to return, so in headers it shows the right status code.
It turned out that err?.code is a string, so it would throw an error inside res.code function since it wants a number.

nodejs promisify a callback function with one parameter /callback

util.promisify appears to always expect 2 parameters from a callback function, however the existing functions do not have a seperate callback for err and data, but only a single callback.
How can I handle this ???
const {promisify} = require('util');
function y(text,cb){
setTimeout(function(){cb({error:false,data:text})},1000);
}
async function test(text) {
try{
const z = promisify(y)
return await z(text);
} catch(e) {return {error:true,msg:e}}
}
console.log(test('xxx'));
What I am looking for is to return the value from function y syncronously and not getting a promise i.e.
var x = test('xxx');
Given the information in your comment, you can wrap the function with a compatible signature to be passed directly to promisify():
const { promisify } = require('util')
function y (query, callback) {
callback(query)
}
function yCompatible (query, callback) {
y(query, ({ error, data }) => {
callback(error && data, error || data)
})
}
const yAsync = promisify(yCompatible)
async function test (query) {
try {
return yAsync(query)
} catch (error) {
return error
}
}
test('xxx').then(
data => { console.log(data) },
error => { console.error(error) }
)
Also try not to get in the habit of using single letter variables like a mathematician ;) I realize this is just example code, but even then it's helpful to be a bit more explicit about your intent.

TypeError: obj.hasOwnProperty is not a function when calling Graphql mutation

I get a strange error and can't figure out what I am doing wrong. I wrote a graphql mutation to call an api:
domainStuff: async (parent, { command, params }, { models }) => {
console.log("Params:", params);
const result = await dd24Api(command, params);
return result;
}
This it the function I call:
export default async (command, parameter) => {
const args = _.merge({ params: parameter }, auth);
// Eleminate copying mistakes
console.log(typeof args);
const properCommand = command + "Async";
const result = await soap
.createClientAsync(apiWSDL)
.then(client => {
return client[properCommand](args)
.then(res => {
console.log(res[command + "Result"]);
return res[command + "Result"];
})
.catch(err => {
console.log(err);
return err;
});
})
.catch(err => console.log(err));
return result;
with this query variables:
{
"command": "CheckDomain",
"params": {"domain": "test.it"}
}
The console.log shows me that args is an object, but I get this error (from the first catch block):
TypeError: obj.hasOwnProperty is not a function
How can that be? After all I checked whether it is an object and it is. More strange, if I give a hardcoded object into the query, this for example:
domainStuff: async (parent, { command, params }, { models }) => {
console.log("Params:", params);
const result = await dd24Api(command, {domain: "test.com"});
return result;
}
then it works perfectly fine. What am I doing wrong? Thx for any help in advance.
EDIT: I am using "graphql-server-express": "^0.8.0" and "graphql-tools": "^1.0.0"
If you are using graphql-js there are a lot of places where new objects are created using Object.create(null) which is different from {} you can read an explanation about that here Creating Js object with Object.create(null)?
But essentially an object created with Object.create(null) has no hasOwnProperty method
You can try it in node with
const obj1 = Object.create(null)
console.log(typeof obj1.hasOwnProperty)
// 'undefined'
const obj2 = {}
console.log(typeof obj2.hasOwnProperty)
// 'function'
Another method you can use for determining if an object has a key that will work on an object created with Object.create(null) is
function hasKey(obj, key) {
return Object.keys(obj).indexOf(key) !== -1
}
You can convert it to a standard Object by:
data = JSON.parse(JSON.stringify(data));
Okay, after an extensive period of trial and error I was able to fix the problem. Changing the position of the objects I pass into the .merge function was the solution. The working code is:
const args = _.merge(auth, { params: parameter });
Both are objects, but it seems like the object coming from the graphql variables did not have the required hasOwnProperty method. Simply speaking, instead of copying the "good object" (auth) into the bad one (parameter), I copy the bad one into the good one which has the needed function.
Hopefully this helps someone else who also experiences this error.

Resources