same base url with different functionalities nodejs - node.js

app.get('/api/v3/app/events', async function (req, res){
try {
let unique_id=req.query.id
console.log(unique_id)
database.collection('event').findOne(ObjectId(unique_id),function(err,data){
if(err){
res.json({error:"no data found with specified id"})
}
console.log(data)
res.json(data)}
)
} catch (error) {
console.log("internal error")
res.json({error:error})
}
})
app.get('/api/v3/app/events', function(req,res) {
try {
let limit=parseInt(req.query.limit)
let page =parseInt(req.query.page)
console.log(database.collection('event').find().sort({$natural: -1}).limit(limit).skip(page-1).toArray((err, result) => {
console.log(result);
})
)
} catch (error) {
console.log(error)
return res.json({error:"internal error "})
}
})
I have to perform these functionalities with same base url i.e '/api/v3/app/events'.
Please help . I am successful as I change the names of endpoints, but keeping them same , I gets null and undefined on the console

I'm not sure why do you need both to use same URL, but you have two choices either use a single endpoint with both of the logics. The other option would be to use the next middleware based on the id query param like this:
app.get('/api/v3/app/events', async function (req, res, next){
if (!req.query.id) {
next();
return;
}
// Rest of your endpoint logic
}
Each endpoint in Express is considered as middleware. This means that response won't be sent back, but calling the next() middleware instead and allow other middlewares to be executed. You can use same if or modify it based on your login.

Related

I cant get a response from a POST request with an array in the body, Using NodeJS / Axios and Postman

This is a course quiz and this is the most basic information I need in order to create a React app. But while the endpoint URL is correct, the page "/products" returns a "400" error when I try to request the product list. The instructions I'm given are:
Obtain a list of products with
Route: /products
Body: Array
method: POST
{
"product-codes": [
"98798729",
"84876871",
"29879879",
]
}
My index.js
...
app.post(`/products`, async (req, res) => {
try {
const response = await axios.post(`${apiURL}/products`);
// console.log(response.data);
res.status(200).json(response.data);
} catch (error) {
res.status(400).json({ message: error.message });
}
});
in Postman
I use http://localhost:4000/products
and pass a Body / Raw /JSON:
{
"product-codes": [
"98798729",
"84876871",
"29879879",
]
}
But I can't get in! I am not seeing something obvious because this is the entry point to a very long and complex quiz. Thanks
What I see from the code is a recursive long call.
app.post(`/products`, async (req, res) => {
try {
const response = await axios.post(`${apiURL}/products`); // calling the same end point
// console.log(response.data);
res.status(200).json(response.data);
} catch (error) {
res.status(400).json({ message: error.message });
}
});
You should do something like this:
app.post(`/products`, async (req, res) => {
// do your logic
// when you pass body from postman on this endpoint
// you will receive the body here and save it to DB
// or do the manipulation and then send back the response
res.status(200).json(req.body.data);
});
I highly recommend you to first follow through some tutorials to understand how API works and how to create simple API using Node.js.

Can't set headers after they are sent when using dbquery multiple times

I get this error #Can't set headers after they are sent# when using dbquery multiple times.
Hi, I'm almost new to node.js and I can't figure out why this error appears. If I try with one dbquery then everything is ok. But if I use multiple query then it crashes.
router.get(
'/auth/facebook/token',
(req, res, next) => {
passport.authenticate('facebook-token', (error, user, info) => {
if (user){
myDB.setUser(user.email,(err,pinfo) =>{
if (err) {
res.send(err);
}
else {
res.send(pinfo); <- Crash at this line!!!
}
});
}
next();
})(req,res, next);
}
);
function setUser (email, cb) {
pool.query("INSERT INTO users (email,pinfo) VALUES (?,0)", email, (err, result) => {
if(err){
cb(err);
return;
}
else{
pool.query("SELECT pinfo FROM users WHERE email = ?", email,(err,pinfo) =>{
cb(err,pinfo);
});
}
});
}
You are calling next middle layer function using next(). After sending the response to the user. Try without next or modify your logic to. Hope this will help you
once you are used res.send you cannot use it again
it seems you are sending a response at two positions please check the logic thoroughly
Some Where you sending response twice and hence this error. R.sarkar is right take out next() call and add it somewhere you will want to continue with your next dbquery or else respond from top function only once and never call next().

How to redirect from a feathers.js service

I have a feathers.js service and I need to redirect to a specific page when using post
class Payment {
// ..
create(data, params) {
// do some logic
// redirect to an other page with 301|302
return res.redirect('http://some-page.com');
}
}
Is there a posibility to redirect from a feathers.js service ?
I'm not sure how much of a good practice in feathers this would be, but you could stick a reference to the res object on feathers' params, then do with it as you please.
// declare this before your services
app.use((req, res, next) => {
// anything you put on 'req.feathers' will later be on 'params'
req.feathers.res = res;
next();
});
Then in your class:
class Payment {
// ..
create(data, params) {
// do some logic
// redirect to an other page with 301|302
params.res.redirect('http://some-page.com');
// You must return a promise from service methods (or make this function async)
return Promise.resolve();
}
}
Found a way to do this in a more friendly manner:
Assuming we have a custom service:
app.use('api/v1/messages', {
async create(data, params) {
// do your logic
return // promise
}
}, redirect);
function redirect(req, res, next) {
return res.redirect(301, 'http://some-page.com');
}
The idea behind is that feathers.js use express middlewares and the logic is the following one.
If the chained middleware is an Object, then it is parsed as a service, after you can chain any number of middlewares you want.
app.use('api/v1/messages', middleware1, feathersService, middleware2)

Response with JSON on request-promise .catch() function

I've found that all my request-promise .catch() methods are using the same logic in my application. So, I would like to write one maintainable function like so:
var handleError = function (error) {
if (error.statusCode == 401) {
res.json({
'message': 'You\'re no longer logged in. Please check your settings and try again.'
});
} else {
res.json({
'message': 'Something when wrong and it wasn\'t your fault. Please try again.'
});
}
};
router.get('/test', function(req, res, next) {
request({
uri: 'http://google.com/404'
}).then(function () {
console.log('It worked!');
}).catch(handleError);
});
Although this doesn't work because the handleError() function doesn't have access ExpressJS's response object. How can I return JSON to the page and still maintain everything from one function?
In that case, it's best to write a middleware to handle it.
Alternatively, you can bind res object but again you will have to bind it everywhere to use.
You can learn more about express middleware on its homepage
Also, see express-promise package

Sails js beforeCreate next() callback

I am using sails js for my web application. I have to change the default behaviour of beforeCreate. First look at the code:
beforeCreate: function(values, next) {
//ParamsCheck is my service and 'check' is method which will validate the
//parameters and if any invalid parameter then error will be thrown, otherwise
//no error will be thrown
ParamsCheck.check(values)
.then(() => {
// All Params are valid and no error
next();
})
.catch((err) => {
//Some errors in params, and error is thrown
next(err);
});
}
So, the problem is if there is any error, then next method is automatically redirecting to serverError with error code 500, while I want to redirect it with my custom response(eg : badRequest , err code 400). How to achieve this?
You are performing some kind of validation in beforeCreate. However this is not the correct place for validation.
A better approach is to use custom validation rules as described here http://sailsjs.org/documentation/concepts/models-and-orm/validations#?custom-validation-rules or create a policy to handle the validation.
I like to use policies:
module.exports = function(req, res, next) {
var values = req.body;
ParamsCheck.check(values).then(() => {
return next();
}).catch((err) => {
return res.send(422); // entity could not be processed
});
};

Resources