Cant get body from axios.delete server side - express

I am having trouble accessing the data I am sending with my axios.delete() function, to do things on the backend.
This is my axios call:
export const deleteBooking = (email, bookingObjId) => {
console.log("Parameters are both strings and received properly"
, email, bookingObjId)
const response = axios.delete(`/users`,
{data: {userId: email, bookingId: bookingObjId}})
return response
}
This is my code receiving it:
bookingRouter.delete('/', async(req, res) => {
body = req.body
console.log("body receives nothing, it's just {}", body)
var id = mongoose.Types.ObjectId(body.bookingId)
const deleted = await User.updateOne({email: body.userId},
{$pull: {'bookings': {'_id':id}}}, {safe: true, multi: true})
res.status(200).json(deleted)
})
I have tried req.params as well, and that doesn't work. This seems like a simple fix but I can't find it after looking for hours. I know it's not anything mongoose or react related though, it can't be.

Here is the solution I find right after posting this after searching for hours:
const response = axios.request({
method: 'delete',
url,
data
})
works, as per: https://github.com/axios/axios/issues/3220#issuecomment-688566578

Related

Post request with useAxios

I am trying to use the composition api on my Vue app, and I need to do a post request to my backend api. I am trying to make use of the "useAxios" utility from vueuse, but I can't figure out how to pass data into a post request. It isn't shown properly in the docs...
I want to convert the following axios request into one that uses "useAxios".
await axios.put(`/blog/posts/${route.params.postID}/`, post.value)
.then(() => notification = "Post Created!")
.catch(() => {
error = "Failed to create post"
});
I tried setting the value of the data field, but that didn't work...
const {data, execute, isFinished} = useAxios(axios)
data.value = post
await execute(`/admin/blog/posts/${route.params.postID}/`, {method: "PUT"})
I also tried passing the post object into the execute method as a parameter, but my ide complained.
Thanks in advance!
Set up your pending request ahead of time:
const { data, execute, isFinished } =
useAxios(`/admin/blog/posts/${route.params.postID}/`,
{ method: "PUT" },
{ immediate:false });
Then in the future you can call it by passing the data as follows:
const requestBody = { /* your data */ };
await execute({ data: requestBody });

Frontend to Backend POST request is not yielding the data I want

I'm currently working on a project using a React frontend and an Express backend. Currently, when I make a GET request to retrieve data from the backend, everything is working fine. However, I'm unable to POST data to the backend and gain access to the data that's being sent. I'm getting an OK message so the request is going through, but when I log the request data in the backend, I get a message like this which is a jumble of random fields.
Here is the code snippit in the front end for the POST request
const makePost = (data) => {
fetch('http://localhost:5000/api', {
method: 'POST',
headers: {"Content-Type": "application/json", "Access-Control-Allow-Origin": "*"},
body: JSON.parse(JSON.stringify(data))
}).then(function(response){
console.log(response.text())
})
}
Here is my backend which handles the POST request
const express = require('express');
const app = express();
const cors = require('cors');
app.use(cors({
origin: '*'
}));
app.get('/api', (req,res) => {
res.json(menuItems);
});
app.post('/api', (req,res) => {
console.log(req)
})
app.listen(5000, () => console.log("server started on port 5000"));
In the code snippit above, console.log(req) is what was logged in the screenshot linked above.
In your Express server POST API, you are not returning any data, it may cause problems. This is a sample POST API using Axios, Express, React, and MongoDB.Hope it would help you.
//POST API
app.post('/services',async(req,res)=>{
const service = req.body;
const result = await servicesCollection.insertOne(service);
console.log(result);
res.send(result)
});
In client-side POST api:
const onSubmit = data => {
axios.post('http://localhost/services', data)
.then(res=>{
if(res.data.insertedId){
alert('data added successfully');
reset();
}
})
sample post API:
app.post('/book', (req, res) => {
const book = req.body;
// Output the book to the console for debugging
console.log(book);
books.push(book);
res.send('Book is added to the database');
});
Pls take a look at this link: https://riptutorial.com/node-js/example/20967/post-api-using-express

How to sign JSON responses in Express

I'm developing an Express.js server; since it manages sensible data, I'd like to add a cryptographic signature to every response, using a private key. The signature part is already OK, the problem is catching the JSON string just before is sent to the client to sign it.
Ideally I'd like to add a custom response header, e.g. X-signature, so clients could verify the received payload against the public key exposed by the service.
In Express, how can I intercept the response body after the JSON.stringify() call but before the headers are sent?
I've copied what is done in the compression() middleware, replacing the send() method of Response with my own and calling the original one after I calculate the signature. Here's a simplified solution just to show the concept, in the real word I've taken care of body's possible types. The fact that calculateSignature() is an async function is a little troublesome, but everything seems to work well now.
Any comment is appreciated!
import express, { RequestHandler } from 'express';
declare const calculateSignature = (payload: string) => Promise<string>;
const responseSignature = (): RequestHandler => (_, res, next) => {
const _send = res.send;
res.send = (body) => {
if (isPlaintextType(body)) {
calculateSignature(body)
.then((signature) => res.setHeader('X-Signature', signature))
.catch((e) => console.error(e))
.finally(() => _send.call(res, body));
return res;
} else {
return _send.call(res, body);
}
};
next();
};
const app = express();
app.use(responseSignature());
app.listen(3000);

'return res.json' isn't stopping my request as expected?

I created some sample code to demonstrate my issue on a smaller scale. I would like a solution that doesn't involve adding 'unique: true' to my model, if possible, because I seem to run into similar problems in many different scenarios:
const express = require('express')
const mongoose = require('mongoose')
const app = express()
const PORT = 6000
app.use(express.json())
// Initializing mongoose model and connection
const SampleSchema = mongoose.Schema({
username: String,
password: String
})
const Sample = mongoose.model('sample', SampleSchema)
mongoose.connect('mongodb://localhost/testdatabase', {
useNewUrlParser: true,
useUnifiedTopology: true
})
// Running my post request
app.post('/api', async (req, res) => {
await Sample.findOne({
username: req.body.username
}).then(data => {
if(data) {
console.log(data)
return res.json('This user already exists in my database')
}
})
await Sample.create({
username: req.body.username,
password: req.body.password
})
return res.json('User created')
})
app.listen(PORT, () => {
console.log('Server running on 6000')
})
Here is my request and database the first time I send a request:
This is as intended. However, if I send the same request a second time:
I want the code to stop on the first 'res.json' if that line of code is executed - basically, in this example I don't want to create a new Sample if one with the same username already exists. I do realize that in this case I can approach the issue differently to solve the problem, but I want to know why my 'Sample.create' line runs, and if there's a way to prevent it from running aside from the aforementioned method.
This is because the .then callback executes after the enclosing function has already finished. In this code here:
await Sample.findOne({
username: req.body.username
}).then(data => {
if(data) {
console.log(data)
return res.json('This user already exists in my database')
}
})
The function being returned from is the data => ... arrow function passed to .then, not the enclosing request handler, so it doesn't prevent subsequent code from executing.
You want to rewrite that bit to use async/await syntax as well:
const data = await Sample.findOne({
username: req.body.username
})
if(data) {
console.log(data)
return res.json('This user already exists in my database')
}
You might want to read up a bit on async/await and Promises in general-- asynchronous code can be quite confusing at first! https://developers.google.com/web/fundamentals/primers/async-functions

Forward decoded POST data to other URL using Express

Some background information:
I have a temperature sensor which is connected via LoRaWAN.
The data from the sensor is encoded, but the manufacturer of the sensor provides a decoder (node app).
I want to show the data in Thingsboard.
Now I was thinking to build a simple express API (I'm new to Express) as a kind of middleware.
The only purpose is to receive the encoded data, decode it (output is in JSON format), and pass it on to Thingsboard.
With the last step I need some help. This is my route:
const decoder = require('../helpers/decoder');
module.exports = app => {
app.post('/', (req, res) => {
const data = {
type: req.body.productType,
payload: req.body.payloadValue
};
const jsonData = decoder.decode(data.type, data.payload);
// jsonData needs to be forwarded/redirected Thingsboard
});
};
Can anyone point me in the right direction, how to pass on the "handled" POST data and pass it on to another URL (Thingsboard HTTP endpoint URL)
Thanks in advance!
💡 This is not the best practice, but if you want to read some data from some route in another route without passing them when the route was called then you can try this code below: 👇
const express = require('express');
const app = express();
app.post('/', (req, res) => {
app.locals['decoder'] = { data: "This is my decoder data"};
res.send('Successfully to add decoder data');
});
app.get('/', (req, res) => {
res.send(app.locals['decoder']);
} )
app.listen(3000, () => {
console.log('Server is up');
});
⚠️ It should be noted that the code above is only an example of how to read data from one route on another route.
Another option:
👨‍🏫 You can create a middleware that is used to decode your payload and use the middleware on each route that requires the results of the decoded payload.
⚠️ But, it should be noted that for this problem, you must leave a payload on each route that requires decoded results, so that it can be decoded.
Updated: Passing Data To External Endpoint
💡 If You want to pass the data to an external endpoint or another website, see code below: 👇
const axios = require('axios');
app.post('/', (req, res) => {
const decoder = { data: "This is my decoder data"};
// method of external-endpoint: e.g: POST
axios.post('https://www.example-website.com/api/v1/example-endpoint', decoder)
.then(response => {
console.log(response);
}).catch(ex => {
console.log(ex);
})
})
You can use that route above in the example express server in addition to this answer.
I hope it's can help you 🙏.