how can we use delete http request in NodeJS - node.js

when i try to delete data by this code its not working
router.delete('/delete-screen/:id',(req,res)=>{
let proId=req.params.id
console.log(proId)
theaterHelpers.deleteOwner(proId).then((response)=>{
res.redirect('/theater/screens')
})
})
but using this code it working
router.get('/delete-screen/:id',(req,res)=>{
let proId=req.params.id
console.log(proId)
theaterHelpers.deleteOwner(proId).then((response)=>{
res.redirect('/theater/screens')
})
})
what i done is replace delete to get, My question is how can make a http delete request in my code
my delete function code is
deleteScreen:(screenId)=>{
return new Promise((resolve,reject)=>{
db.get().collection(collection.SCREEN_COLLECTION).removeOne({_id:ObjectID(screenId)}).then((response)=>{
console.log(response)
resolve(response)
})
})
}

If you're using a server-rendered application, then you can only issue GET and POST requests. The only way to trigger a delete route handler is to trick your application into thinking the incoming request actually has DELETE semantics. You can do this by modifying the request.method property before the request is actually handed to the router.
There are a number of ways to achieve this, and the method-override package has got you covered.
For instance, the following setup would update request.property for incoming GET requests to the value provided with the _method query parameter.
var methodOverride = require('method-override')
app.use(methodOverride("_method", { methods: ["GET"] }))
Then, accordingly add a _method query parameter with the DELETE value to the url you want to use to trigger you delete route handler.
yourUrl?_method=DELETE
https://www.npmjs.com/package/method-override

Related

disable http method in express js

im doing nessus testing on my express app
and here what i get
Based on tests of each method :
HTTP methods ACL CHECKOUT COPY DELETE GET HEAD LOCK MERGE
MKACTIVITY MKCOL MOVE NOTIFY OPTIONS PATCH POST PROPFIND
PROPPATCH PUT REPORT SEARCH SUBSCRIBE TRACE UNLOCK UNSUBSCRIBE
are allowed on :
/
/login
/styles
i done some search and actually end up here.
disable HTTP methods, TRACK TRACE etc
the solution
const allowedMethods = ['GET','HEAD','POST'];
function onrequest(req, res) {
if (!allowedMethods.includes(req.method))
return res.end(405, 'Method Not Allowed');
// ...
}
however i do not understand how to use the solution,
#kiksy comment that: This method would sit in your front controller. eg from here: expressjs.com/en/starter/hello-world.html You would add it to line 3
but line 3 was "const port = 3000"
it makes me confused
could someone help me on that
FYI, i could not comment becoz i dont have 50 rep
The comment is essentially saying that you can add this to any of your routes and you're checking the incoming method from each request to see if it is one of the whitelisted HTTP methods, and if not, you're going to return a 405 to let the user know that the method they've tried to hit is unsupported.
You could use a middleware to blanket this for all requests.
const allowedMethods = ['GET', 'HEAD', 'POST']
app.use((req, res, next) => {
if (!allowedMethods.includes(req.method)) return res.end(405, 'Method Not Allowed')
return next()
})

how can I get an element in a redirect url using node.js

Non-English country, please forgive my spelling mistakes.
For example, I want to first redirect url1(http://localhost:3000/api/song/167278) to url2(http://localhost:4000/api/song/167278) to use url2's api. And url2 will reponse a json file, which can be seen in the postman's panel.
(postman's pannel)
But there maybe a lot of elements, I only want an element in the file, such as data[0].url. How can I return just return the url value (data[0].url in this json) when people access http://localhost:3000/api/song/167278.
I am using express.js now, how can I edit it? Or is there any other methods?
app.get('api/song/:id', async (req, res) => {
try {
const { id } = req.params
url = "http://localhost:4000/api/song/" + id
res.redirect(url)
}
catch (e) {
console.log(e)
}
}
You could either proxy the entire request there or fetch localhost:4000/api/song/1 in your request handler (with something like node-fetch or axios or with node's APIs and send the fields that you want back to the client as json.

Call Express router manually

Нello! I am looking to call a function which has been passed to an expressRouter.post(...) call.
This expressRouter.post(...) call is occurring in a file which I am unable to modify. The code has already been distributed to many clients and there is no procedure for me to modify their versions of the file. While I have no ability to update this file for remote clients, other developers are able to. I therefore face the issue of this POST endpoint's behaviour changing in the future.
I am also dealing with performance concerns. This POST endpoint expects req.body to be a parsed JSON object, and that JSON object can be excessively large.
My goal is to write a GET endpoint which internally activates this POST endpoint. The GET endpoint will need to call the POST endpoint with a very large JSON value, which has had URL query params inserted into it. The GET's functionality should always mirror the POST's functionality, including if the POST's functionality is updated in the future. For this reason I cannot copy/paste the POST's logic. Note also that the JSON format will never change.
I understand that the issue of calling an expressjs endpoint internally has conventionally been solved by either 1) extracting the router function into an accessible scope, or 2) generating an HTTP request to localhost.
Unfortunately in my case neither of these options are viable:
I can't move the function into an accessible scope as I can't modify the source, nor can I copy-paste the function as the original version may change
Avoiding the HTTP request is a high priority due to performance considerations. The HTTP request will require serializing+deserializing an excessively large JSON body, re-visiting a number of authentication middlewares (which require waiting for further HTTP requests + database queries to complete), etc
Here is my (contrived) POST endpoint:
expressRouter.post('/my/post/endpoint', (req, res) => {
if (!req.body.hasOwnProperty('val'))
return res.status(400).send('Missing "val"');
return res.status(200).send(`Your val: ${req.body.val}`);
});
If I make a POST request to localhost:<port>/my/post/endpoint I get the expected error or response based on whether I included "val" in the JSON body.
Now, I want to have exactly the same functionality available, but via GET, and with "val" supplied in the URL instead of in any JSON body. I have attempted the following:
expressRouter.get('/my/get/endpoint/:val', (req, res) => {
// Make it seem as if "val" occurred inside the JSON body
let fakeReq = {
body: {
val: req.params.val
}
};
// Now call the POST endpoint
// Pass the fake request, and the real response
// This should enable the POST endpoint to write data to the
// response, and it will seem like THIS endpoint wrote to the
// response.
manuallyCallExpressEndpoint(expressRouter, 'POST', '/my/post/endpoint', fakeReq, res);
});
Unfortunately I don't know how to implement manuallyCallExpressEndpoint.
Is there a solution to this problem which excludes both extracting the function into an accessible scope, and generating an HTTP request?
This seems possible, but it may make more sense to modify req and pass it, rather than create a whole new fakeReq object. The thing which enables this looks to be the router.handle(req, res, next) function. I'm not sure this is the smartest way to go about this, but it will certainly avoid the large overhead of a separate http request!
app.get('/my/get/endpoint/:val', (req, res) => {
// Modify `req`, don't create a whole new `fakeReq`
req.body = {
val: req.params.val
};
manuallyCallExpressEndpoint(app, 'POST', '/my/post/endpoint', req, res);
});
let manuallyCallExpressEndpoint = (router, method, url, req, res) => {
req.method = method;
req.url = url;
router.handle(req, res, () => {});
};
How about a simple middleware?
function checkVal(req, res, next) {
const val = req.params.val || req.body.val
if (!val) {
return res.status(400).send('Missing "val"');
}
return res.status(200).send(`Your val: ${val}`);
}
app.get('/my/get/endpoint/:val', checkVal)
app.post('/my/post/endpoint', checkVal)
This code isn't tested but gives you rough idea on how you can have the same code run in both places.
The checkVal function serves as a Express handler, with request, response and next. It checks for params first then the body.

How to set Routes for APIs

I am building an API to manage meetups with nodeJS. I have build an endpoint with the route "/meetups/:id/" to fetch a specific meetup record by its id. And then I want to fetch all the upcoming meetup records and I tried to use "/meetups/upcoming/" but when I query it, I get the not found error (404). It seems like the second route is not recognised.
Here is the code defining the two routes
the request from postman
Any help on how can I handle that?
Thanks.
Route is '/api/v1/meetups/upcoming/all'. Move res.status outside the map function.
EDIT: you'll have to change the route which has to be different from api/v1/meetups/:id. Reason is when route '/api/v1/meetups/upcoming' is requested express sees it as the same route as before and takes 'upcoming' as the parameter.
app.get("/api/v1/meetups/upcoming/all", function(req, res) {
var today = new Date();
var upcomings = db.meetups.map(function(meetup) {
if(meetup.happeningOn > today) {
return meetup;
}
});
res.status(200).send({
status: 200,
data: upcomings
});
});
You need to move the res.status piece outside of the const upcomings definition.

Node.JS run routes synchronously

In this example, I have two routes - the first is a Get route and the second is a Post route. I want the information gathered in the get route to be included in the post route. I tried using .then and some basic boolean if logic but I cannot get these routes to run synchronously.
leadFormObj = {};
$.get("/getID/"+leadFormObj.parentEmail, function(event){
console.log("getting an ID");
console.log(event[0].id);
leadFormObj.parentID = event[0].id;
});
console.log(leadFormObj);
$.post("/addChild", leadFormObj, function(data) {
console.log(leadFormObj);
console.log("sent");
});
In the example above, I have a standard object (i've shown it blank in this example). The first get route will run and pass in a new key value pair to the object. I then want to pass this updated object to the post route but I'm not sure how to do this.
Would I use nested routes to do this?
Thanks!
Why don't you put the post request inside the callback of the get request
$.get("/getID/"+leadFormObj.parentEmail, function(data){
$.post("/addChild", {parentID: data[0].id}, function(data) {
console.log("sent");
});
});

Resources