Send Image from mobile to Node js server - javascript

I am trying to send an image from mobile (I took photo) and send to NodeJS from React without success.
Here is the piece of code.
ReactJS
const formData = new FormData();
formData.append("data", {
uri: imageURI,
name: "photo",
type: "image/jpg",
});
const resp = await fetch(URL + "/send", {
method: "POST",
body: formData,
headers: { "Content-Type": "multipart/form-data" }
}).then(async (res) => {
console.log(res);
});
And here is the NodeJS code:
const express = require('express');
const bodyParser = require('body-parser');
const port = process.env.PORT || 3000;
const server = require("http").createServer();
const fs = require('fs');
let multiparty = require('multiparty');
const app = express();
app.use(bodyParser.urlencoded({
extended: false,
type: 'multipart/form-data'
}));
//https://stackoverflow.com/questions/56748415/req-body-is-empty-in-node
app.post('/send', (request, response, next) => {
console.log(request.body);
console.log(request.body.data);
fs.writeFile('result.png', request.body, function(err) {
console.log('File created: result.png');
});
response.send('uploaded!')
});
//Start the Server
server.on("request", app);
server.listen(port, function() {
console.info(`PPT Server: ${server.address().port}`);
});
I am getting this error.
fs.js:1253
data : Buffer.from('' + data, options.encoding || 'utf8');
^
TypeError: Cannot convert object to primitive value
at writeFd (fs.js:1253:29)
at fs.js:1247:7
at FSReqCallback.oncomplete (fs.js:146:23)
How can I be able to save the uploaded image?

Related

post request in node app return 404 not found in cpanel

I use the mvc routing in my node app and Whenever I post a request to the cpanel server side (route file) for processing in my node app I receive a 404 error but the route are accurate when I checked. but it works well on localhost andon cpanel when i try not to use mvc routing i.e post and receive the request in app.js.
Frontend Code:
$.ajax({
url: "/rest",
method: "post",
contentType: "application/json",
data: JSON.stringify({
email: 'akpulufabian#gmail.com', password: '0000'
}),
success: (data) => {
console.log(data)
}
});
Backend Code [route file]
const express = require("express");
const bodyParser = require('body-parser');
const parser = bodyParser.json({ limit: '16mb'});
const { rest, index } = require('../controllers/rest');
const router = express.Router();
router.get('/index', index);
router.post('/rest', parser, rest);
module.exports = router ;
Backend Code [controller file]
const express = require("express");
const bcrypt = require('bcryptjs');
require('dotenv').config();
const nodemailer = require("nodemailer");
const jwt = require('jsonwebtoken');
const path = require("path");
const fs = require('fs');
const mongodb = require('mongodb');
const { ObjectId, MongoDBNamespace } = require('mongodb');
//const {dbConn} = require('../db');
let db;
const app = express();
const maxAge = 3 * 24 * 60 * 60;
const createToken = (id) => {
return jwt.sign({ id }, 'news app secret', {
expiresIn: maxAge
});
};
const index = (req, res) => {
res.render('rest')
}
const rest = (req, res) => {
res.status(200).send({ user: "test successfully carried out..." })
}
module.exports = {
index,
rest
};

Problem with sending data from Angular to Express

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());

Upload image and read json with express js

Problem:
Trying to get json string but req.body in the post data handler returns undefined. Is it even possible to send json and file in one post request to the server?
Code:
Data sended to the server:
function saveFile(e) {
let info = {titleI: title.value, dirI: dir.value};
let xhr = new XMLHttpRequest();
let formData = new FormData();
let file = e;
formData.append("info", JSON.stringify(info));
formData.append("file", file);
xhr.onreadystatechange = state => { console.log(xhr.status); }
xhr.timeout = 5000;
xhr.open("POST", '/register');
xhr.send(formData);
}
The post data handler:
router.post("/", (req, res) => {
console.log(req.body.info)
var fstream;
req.pipe(req.busboy);
req.busboy.on('file', function (fieldname, file, filename) {
let dirName = "a"
fs.mkdir("D:/node website/ipgrabber/files/"+dirName+"/", function(err) {
if (err) {
console.log(err)
}
})
fstream = fs.createWriteStream("D:/node website/ipgrabber/files/"+dirName+"/" + filename);
file.pipe(fstream);
fstream.on('close', function () {
res.redirect('back');
});
});
})
This is the main class:
var express = require('express')
var http = require('http')
const mongoose = require('mongoose')
const { json } = require('express')
var cookieParser = require('cookie-parser')
var app = express()
var server = http.createServer(app)
const bodyParser = require('body-parser')
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: true}));
var busboy = require('connect-busboy');
app.use(busboy());
//error handler
mongoose.connect('mongodb://localhost:27017/grabber', {useNewUrlParser: true, useUnifiedTopology: true});
app.use(cookieParser())
app.set("view engine", "ejs")
app.set('views', __dirname+'/views/html/');
app.use("/js", express.static(__dirname + "/views/js"))
app.use("/css", express.static(__dirname + "/views/css"))
const registerRoute = require("./routes/register")
const grabberRoute = require("./routes/grabber")
app.use("/register", registerRoute)
app.use("/id", grabberRoute)
app.get("/", (req, res) => {
res.redirect("/register")
})
app.use(function (err, req, res, next) {
res.status(400).send("Error code: 2 <hr> This page is currently inaccessible! <br> <a href='/'>GO TO HOMEPAGE</a>")
console.log(err)
})
server.listen(80)
Project resources:
body-parser - 1.19.0
connect-busboy - 0.0.2
cookie-parser - 1.4.5
crypto-js 4.0.0
ejs 3.1.5
express 4.17.1
mongoose 5.11.19
By default, express can't manage to get multipart/form-data correctly.
You have to use a middleware to handle and parse this request.
I recommend to use multer.
In your case, you're using connect-busboy so the info should be handled like this:
req.busboy.on('field', function(key, value, keyTruncated, valueTruncated) {
console.log('your info is here', key, value);
});

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.

unable to send post request using socket.io

here i am sending data from socket client to socket server and after receiving the request it has to send to node api
**the issue is im getting null ** on calling the socket server
below is my code
Socket Client
socket.connect();
socket.emit("posreq",JSON.stringify({ "title": "data"}));
Socket Server
var http = require('http'),
io = require('socket.io'), // for npm, otherwise use require('./path/to/socket.io')
request = require('request'),
cors = require('cors'),
server = http.createServer(function (req, res) {
// your normal server code
res.writeHead(200, {
'Content-Type': 'application/json'
});
res.end('Hello world');
});
server.listen(4000);
// socket.io
var socket = io.listen(server);
socket.on('connection', function (client) {
// new client is here!
client.on('posreq', function (postdata) {
request.post("http://localhost:3000/book", {
body: postdata
}, function (res) {
console.log(res);
client.send("post req called",postdata);
});
});
client.on('disconnect', function () {
console.log('connection closed');
});
});
Node api
const express = require('express')
const bodyParser = require('body-parser');
const cors = require('cors');
const app = express()
const port = 3000
let books = [{
"title": "Eloquent JavaScript, Second Edition",
}];
app.use(cors());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.post('/book', (req, res) => {
const book = req.body;
// output the book to the console for debugging
console.log(book);
// books.push(book);
res.json('Book is added to the database');
});
I tried but unable to understand the issue
Note : How can i convert the Socket server to express js code
As far I understand you are willing to use express instead of HTTP and that will solve your problem. And in the below code, I have used express as well as HTTP. Try code below
const express=require("express")
const app=express()
const server=require("http").createServer(app)
const socket=require("socket.io")(server)
server.listen(4000,()=>console.log(`Listening to port 4000`))
socket.on('connection', function (client) {
client.on('posreq', function (postdata) {
request.post("http://localhost:3000/book", {
body: postdata
}, function (res) {
console.log(res);
client.send("post req called",postdata);
});
});
client.on('disconnect', function () {
console.log('connection closed');
});
});
May be you need few modification,
Request is depricated so better to use axios or other alternative.
const express = require("express")
const bodyParser = require("body-parser")
const axios = require('axios')
const app = express()
const httpServer = require("http").createServer(app)
const socket = require("socket.io")(server)
app.use(bodyParser.json({ limit: '16mb' }));
app.use(bodyParser.urlencoded({ limit: '16mb', extended: true, parameterLimit: 50000 }));
app.get('/', (req,res)=> res.send("Hello world"));
socket.on('connection', function (socket) {
socket.on('posreq', async (body) => {
try {
const { data } = await axios.post("http://localhost:3000/book", { body })
socket.send("post req called", data);
} catch (error) {
socket.send("post req error", error);
}
});
socket.on('disconnect', function () {
console.log('connection closed');
});
});
httpServer.listen(3000, () => console.log(`Spinning 3000`))

Categories