Problem with sending data from Angular to Express - javascript

I'm trying to post data from Angular to Express.js
This is my function connected to the button (TypeScript):
upload(): void {
const nameFromId = document.getElementById('taskName') as HTMLInputElement;
this.taskName = nameFromId.value;
const testData = [
{
task: this.taskName,
selectedType: this.selectedType,
selectedSubject: this.selectedSubject
}
];
const body = JSON.stringify(testData);
this.http.post('/api/upload', body)
.subscribe();
"body" is not null
This is express:
const express = require('express');
const path = require('path');
const app = express();
const port = 8080;
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({
extended: true
}));
app.post('/api/upload', (req, res) => {
let task = req.body.task;
let selectedType = req.body.selectedType;
let selectedSubject = req.body.selectedSubject;
console.log("task: " + task);
console.log("type: " + selectedType);
console.log("subject: " + selectedSubject);
console.log("server: " + req.body);
res.end("yes");
})
app.use(express.static(__dirname + '/dist/al'));
app.get('/*', function (req, res) {
res.sendFile(path.join(__dirname + '/dist/al/index.html'));
});
app.listen(process.env.PORT || port);
And this is what I get as a mistake:
mistake from console
If I put extra options to my "post method" from Angular and write something like:
this.http.post('/api/upload', body, {responseType: 'text'})
.subscribe();
After adding responseType: 'text' this mistake is no longer exists, but when it comes to console.log all data, that I posted to express, undefined:
Express console.log
What am I doing wrong?

You are sending a string as http request body.
Don't use JSON.stringify, try sending object as is.
const testData = [
{
task: this.taskName,
selectedType: this.selectedType,
selectedSubject: this.selectedSubject
}
];
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
})
}
this.http.post('/api/upload', testData, httpOptions)
.subscribe();
Also add this line to server:
app.use(bodyParser.json());
Finally:
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());

Related

req.body is empty, why?

I want to send some data to my MongoDB database, but in router.post my req.body is empty, if I use stuff that I put in my send function in User(req.body) instead of req.body data will be send to my MongoDB database correctly.
This is my router that I use, router.get work fine, it return database tables correctly on /api page:
const router = require("express").Router();
const User = require("./model/models");
const parser = require("body-parser").json();
router.get("/", async (req, res) => {
const data = await User.find({});
res.json(data);
});
router.post("/",parser,async (req, res) => {
console.log('1')
console.log(req.body)
console.log('2')
parser.v
await User(req.body).save();
res.json({"msg": "ok"});
});
module.exports = router
This is my index.js file code:
const bodyParser = require('body-parser');
const express = require('express');
const app = express();
const parser = require("body-parser").json();
var path = require('path');
app.use(express.urlencoded(true));
app.use(express.json());
app.use(parser);
app.use('/',require("./routes/routes"))
app.use(express.static(__dirname +'/public'))
app.use("/api", require('./data/api'))
app.listen(5000,function(){
console.log('server is alive')
})
This is function that what I use to send data:
const btn1 = document.getElementById('btnEnter')
let Login = "123"
btn1.addEventListener('click' ,e=>{
send({newsTxT : "someTextHere",newsZag:"someZag",author:"SomeAuthor"})
})
const send = async(body) => {
let res = await fetch("/api", {
method: "post",
header: {
"Content-Type": "application/json",
"Accept": "application/json"
},
body: JSON.stringify(body)
});
let data = await res.json();
console.log(data)
}
The only weird thing I see is that you are using a json body-parser and also the express.json() both technically do the same, but body-parser is deprecated so it might be causing a bug.
Also you don't have to import it again in the routes, placing app.use(express.json()) at index.js will make it work for all endpoints/routes.
See how this refactor goes:
const router = require('express').Router()
const User = require('./model/models')
router.get('/', async (req, res) => {
const data = await User.find({})
res.json(data)
})
router.post('/', async (req, res) => {
console.log('1')
console.log(req.body)
console.log('2')
await User(req.body).save()
res.json({ 'msg': 'ok' })
})
module.exports = router
index.js
const express = require('express')
const app = express()
var path = require('path')
app.use(express.urlencoded(true))
app.use(express.json())
app.use('/', require('./routes/routes'))
app.use(express.static(__dirname + '/public'))
app.use('/api', require('./data/api'))
app.listen(5000, function () {
console.log('server is alive')
})
The following worked fine:
const express = require("express")
const app = express()
const router = express.Router()
router.use(express.json())
app.use(router)
router.post('/api/user', function(req, res) {
// ...
}
I see the difference may be using the: app.use(router)
Note that in the above code the statement:
router.use(express.json())
can be replaced with (using the body-parser):
const bodyParser = require('body-parser')
router.use(bodyParser.json())
This worked fine with express version 4.17.1, body-parser version 1.19.0 and NodeJS version 12.18.3

how do i send FormData to the node server from React js axios post request?

I am trying to send the form data to the node server, the data is showing at the time of request in the network payload but not reaching to the node server.
Request initiator file.
let formData = new FormData();
// formData.append('test', 'hello');
formData.append('productImage', productImage);
// console.log(productName);
formData.append('productName', productName);
formData.append('productDesc', productDesc);
formData.append('productPrice', productPrice);
formData.append('productCategory', productCategory);
formData.append('productQty', productQty);
// var options = { content: formData };
console.log(formData.entries());
createProduct(formData)
.then((response) => {
console.log('server response = ', response);
})
.catch((err) => {
console.log('Error Occurred ', err);
});
}
product.js file
import axios from 'axios';
export const createProduct = async (formData) => {
console.log(formData);
const response = await axios.post('/api/products/', formData);
return response;
};
server.js file
const express = require('express');
const app = express();
const cors = require('cors');
const morgan = require('morgan');
const cookieParser = require('cookie-parser');
const connectDB = require('./database/db');
const authRoutes = require('./routes/auth');
const categoryRoutes = require('./routes/category');
const productRoutes = require('./routes/products');
app.use(cors());
app.use(morgan('dev'));
app.use(express.json());
app.use(cookieParser());
// app.use(express.json());
app.use('/api/auth', authRoutes);
app.use('/api/category', categoryRoutes);
app.use('/api/products', productRoutes);
connectDB();
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`listening to port ${port}`));
routes/products.js
const express = require('express');
const router = express.Router();
const productsController = require('../controllers/products');
const { authenticateJWT } = require('../middleware/authenticator');
router.post('/', authenticateJWT, productsController.create);
// router.get('/', authenticateJWT, categoryController.readAll);
module.exports = router;
controllers/products.js
const Products = require('../models/Products');
exports.create = async (req, res) => {
// const { product } = req.file;
console.log(req.body);
try {
// const categoryExists = await Category.findOne({ category });
// let newProduct = new Products();
// newProduct.product_name = ;
// newProduct = await newProduct.save();
res.status(200).json({
successMessage: ' was created',
});
} catch (err) {
console.log('Category create error', err);
return res.status(500).json({
errorMessage: 'Please try again later',
});
}
};
It shows the empty object in the console while printing the req.body.
GET /api/category/ 304 2935.667 ms - -
[0] {}
[0] POST /api/products/ 200 4.827 ms - 34
see the network payload shows the data.
can anyone help me??
Try changing
headers: { 'Content-Type': 'multipart/form-data' }
To
headers: { 'Content-Type': 'application/json' }
and add the following line
app.use(bodyParser.urlencoded({ extended: true })); //this line is already mentioned above
app.use(bodyParser.json());//add this line
Try to add content type to headers on axios.post.
export const createProduct = (formData) => {
return axios({
method: 'post',
url: '/api/products/',
data: formData,
headers: { 'Content-Type': 'multipart/form-data' }
});
};
Also use bodyParser.urlencoded() middleware on server side.
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));
You will get data from req.body.

node.js post method req.body undefined even with body-parser

Hello guys I am working with node js to use dialogflow chat bot ,
I am trying to get parameters from http request post methode
I used postman for that and yes I did set up the content type to json in the header , I have the following code for my request body :
{
"text":"hello"
}
and the following link
http://localhost:5000/api/df_text_query
I have the following index.js file :
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
require('./routes/dialogFlowRoutes')(app);
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }))
app.get('/',(req , res)=>{
res.send({'hello':'Johnny'});
});
const PORT = process.env.port || 5000;
app.listen(PORT);
this my dialogflowRoutes.js file :
const dialogflow = require('dialogflow');
const config = require('../config/keys');
const sessionClient = new dialogflow.SessionsClient();
const sessionPath = sessionClient.sessionPath(config.googleProjectID, config.dialogFlowSessionID);
module.exports = app => {
app.get('/', (req, res) => {
res.send({ 'hello': 'world!' })
});
app.post('/api/df_text_query', async (req, res) => {
console.log(req.body)
const request = {
session: sessionPath,
queryInput: {
text: {
text: req.body.text,
languageCode: config.dialogFlowSessionLanguageCode
}
}
};
let responses = await sessionClient
.detectIntent(request);
res.send(responses[0].queryResult)
});
app.post('/api/df_event_query', (req, res) => {
res.send({ 'do': 'event query' })
});
}
this is the error I get when I send the following request
dialogFlowRoutes.js:17
text: req.body.text,
^
TypeError: Cannot read property 'text' of undefined
Order in which you initialize middleware matters.
You must parse body before you act on it. Move your routing middleware after you initialize bodyParser, like below:
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }))
require('./routes/dialogFlowRoutes')(app);

Put request req.body is empty

As all my requests are working fine, I have a problem with the put. req.body stays empty and then gives that error :
errmsg: "'$set' is empty. You must specify a field like so: {$set:
{: ...}}"
PUT :
router.put('/books/:name', (req, res, next) => {
const localdb = db.client.db(process.env.DB_NAME);
const collection = localdb.collection(process.env.COLL_BOOKS);
collection.replaceOne(
{ "name": req.params.name },
{ $set: req.body },
function (err) {
if (err) throw err
res.status(201).send(true);
});
App.js
const express = require('express'),
app = express();
os = require('os');
const bodyParser = require('body-parser');
const cors = require('cors');
const router = require('./router.js')
require('dotenv').config()
app.use(cors());
app.use(bodyParser.json());
app.use('/api/v1', router);
const port = (process.env.PORT || '3001');
let server = app.listen(port, os.hostname(), () => {
let host = server.address().address,
port = server.address().port;
console.log("Example app listening at http://%s:%s", host, port);
});
axios request :
updateItem = newBook => {
Axios.put(process.env.REACT_APP_API_PATH_BOOKS + `${newBook.name}`, newBook)
.then(res => {
this.setState({ newBook: res.data });
this.props.history.push('/admin');
})
.catch(err => console.log(err));
}
I don't understand what I am doing wrong
Make sure you don't have any middlware stripping or incorrectly parsing the body. For instance, you may have a JSON body parser, and not be sending JSON data with JSON application headers.
Can you give a bit of context, in code, for how you are making the put request and also the result of logging the req in a pastebin?

Request Body gone in NuxtJS ServerMiddleware Express API

I am practicing ExpressJS with NuxtJS. I am expecting to get data from axios POST request but always came up empty on the req.body and req.params. Below are my configuration and snippets
nuxt.config.js
...
serverMiddleware: [
{ path: '/api', handler: '~/api/index.js' }
],
...
api/index.js
const express = require('express')
// Create express instance
const app = express()
// Require API routes
const staticDeploy = require('./routes/static-deploy')
// Import API Routes
app.use(staticDeploy)
// Export express app
module.exports = app
// Start standalone server if directly running
if (require.main === module) {
const port = process.env.PORT || 3001
app.listen(port, () => {
console.log(`API server listening on port ${port}`)
})
}
api/routes/static-deploy.js
const { Router } = require('express')
var CryptoJS = require('crypto-js')
const router = Router()
router.post('/static-deploy', (req, res) => {
console.log('req: ' + req.url) // Returns "req: /static-deploy/"
console.log('req: ' + req.body) // Returns "req: undefined"
console.log('req: ' + JSON.stringify(req.params)) // Returns "req: {}"
console.log('req headers: ' + JSON.stringify(req.headers)) // Returns "req headers: {"accept":"application/json, text/plain, */*","content-type":"application/json;charset=utf-8","user-agent":"axios/0.19.2","content-length":"12","host":"localhost:3000","connection":"close"}"
const STATIC_DEPLOY_AUTH = {
username: 'virus',
password: 'pass1234',
secret: 'utf81234'
}
var bytes = CryptoJS.AES.decrypt(req.body, STATIC_DEPLOY_AUTH.secret)
var decryptedBody = bytes.toString(CryptoJS.enc.Utf8)
if (
decryptedBody.username === STATIC_DEPLOY_AUTH.username &&
decryptedBody.password === STATIC_DEPLOY_AUTH.password
) {
console.log('Authentication successful')
res.send('Ok')
}
})
module.exports = router
Node CLI commands
const CryptoJS = require('crypto-js')
const axios = require('axios')
const ciphertext = CryptoJS.AES.encrypt(
'{"username": "virus", "password": "pass1234"}',
'utc81234'
).toString()
axios.post('http://localhost:3000/api/static-deploy/', ciphertext).catch(error => {
console.log('Error: ' + error)
})
The fix is to add the snippet below in api/index.js:
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
As mentioned in https://aslamdoctor.com/blog/simple-crud-app-using-express-nuxtjs-using-servermiddleware-part-1-2/239

Categories