Send multiple files from express server to rest api - node.js

I am trying to send multiple files from react to express server and then to microservice. The problem is that my express server is getting crashed whenever I try to upload multiple files.
Here is my express.js side code:
router.post("/upload-files", upload.array("file[]"), async function (req, res) {
let check = new FormData();
// check = req.files;
const file = req.files;
// console.log("DATA------------------------>", file);
// check.append("file", file.buffer, file.originalname);
await axios.post(
constants.URL2 +":9095/upload-files", check,
{
headers: {
...check.getHeaders(),
},
})
.then((res) => {
return res;
})
.then((result) => {
res.send(result.data);
});
});
Here is my React.js side code:
update = () => {
if (this.isValidForm()) {
$(".loader").css({ display: "block" });
$(".overlay").css({ display: "block" });
// const obj = {
// fullName: this.state.fullName,
// };
var formData = new FormData();
const size = this.state.fileData;
for (let i = 0; i < size.length; i++) {
console.log(this.state.fileData[i]);
formData.append("file[]", this.state.fileData[i]);
}
// formData.append("files", this.state.fileData);
const updateRequest = {
method: "POST",
headers: {
// "Content-Type": "application/json",
Authorization:
},
// body: JSON.stringify(obj),
body: formData
};
fetch(URL.BASE_URL + "upload-file", updateRequest)
.then((res) => {
if (res.status == 401) {
this.props.GETLOGGEDINUSER(null);
this.props.history.push("/");
} else {
return res.json();
}
})
.then((res) => {
if (res.statusCode == 0) {
this.props.history.push({
pathname: "/newScreen",
state: { notification: "File uploaded Successfully" },
});
toast.success("File uploaded Successfully");
$(".loader").css({ display: "none" });
$(".overlay").css({ display: "none" });
} else {
toast.error(res.message);
$(".loader").css({ display: "none" });
$(".overlay").css({ display: "none" });
}
});
} else {
}
};
I tried many ways to solve this but none of them works.

Related

Nextjs - Autodesk Forge upload to S3 bucket

I'm trying to upload a file to an s3 bucket as per this guide. https://forge.autodesk.com/en/docs/model-derivative/v2/tutorials/translate-to-obj/about-this-tutorial/ and I'm stuck on step 4 - finalize upload. I'm getting failed with a status code of 400 when calling await finalizeUpload() in the handler.put method.
Here is the api route I am using
const upload = multer({
storage: multer.diskStorage({
destination: './public/uploads',
filename: (req, file, cb) => cb(null, file.originalname),
}),
})
handler.use(upload.single('model'))
handler.put(async (req, res) => {
const { _id: projectId } = req.query
const token = await getInternalToken()
const { access_token } = token
const file = req.file
const objectKey = file.originalname
try {
const projectsCollection = await getProject(projectId)
const bucketKey = projectsCollection.project.bucket.bucketKey
const signeds3upload = await obtainSignedUrl(bucketKey, objectKey, access_token)
const { uploadKey, urls } = signeds3upload
await uploadFile(urls, file.path)
await finalizeUpload(bucketKey, objectKey, uploadKey, access_token)
res.status(201).json({ bucketKey, objectKey, uploadKey })
} catch (error) {
console.log(error)
}
})
Here are the functions for steps 2 - 4
const obtainSignedUrl = async (bucketKey, objectKey, token) => {
const payload = {
ossbucketKey: bucketKey,
ossSourceFileObjectKey: objectKey,
access: 'full',
policyKey: 'transient',
}
const config = {
method: 'get',
url: `https://developer.api.autodesk.com/oss/v2/buckets/${bucketKey}/objects/${objectKey}/signeds3upload?minutesExpiration=30`,
headers: {
ContentType: 'application/json',
Authorization: `Bearer ${token}`,
},
}
try {
let res = await axios(config, payload)
return res.data
} catch (error) {
if (error.response) {
console.log('response Error obtainSignedUrl')
} else if (error.request) {
console.log('Request Error')
} else if (error.message) {
console.log('Message Error')
}
}
}
async function uploadFile(signed_upload_url, path_to_file) {
console.log(path_to_file)
const config = {
method: 'put',
url: signed_upload_url,
headers: {
ContentType: 'application/octet-stream',
},
}
try {
let res = await axios(config, path_to_file)
return res.data
} catch (error) {
if (error.response) {
console.log('response Error Upload File', error.message)
} else if (error.request) {
console.log('Request Error')
} else if (error.message) {
console.log('Message Error')
}
}
}
const finalizeUpload = async (bucketKey, objectKey, uploadKey, token) => {
const config = {
method: 'post',
url: `https://developer.api.autodesk.com/oss/v2/buckets/${bucketKey}/objects/${objectKey}/signeds3upload`,
headers: {
ContentType: 'application/json',
Authorization: `Bearer ${token}`,
},
}
try {
let res = await axios(config, uploadKey)
return res.data
} catch (error) {
if (error.response) {
console.log('response Error Finalize upload', error.message)
} else if (error.request) {
console.log('Request Error')
} else if (error.message) {
console.log('Message Error')
}
}
}
Here same error. Solved with
let res = await axios(config, JSON.stringify({uploadKey}))

How to implement Gpay payment gateway in NodeJS?

I tried it in html and javascript it's working perfect in web (mobile's browser).I am using angular for frontend and node for backend but not getting any solution for redirect Playstore or Gpay for mobile browser. Basically I want to implement for mobile browser.
this is my node for backend code & for frontend I already paste static--
const canMakePaymentCache = 'canMakePaymentCache';
onBuyClicked();
function readSupportedInstruments() {
let formValue = {};
formValue['pa'] = keys.GPAY_MERCHANT_ID;//merchantId
formValue['pn'] = `Test_Gpay_Name`;//transactionId
formValue['tn'] = 'Testing Messages ';//message
formValue['mc'] = 'merchant Code';//
formValue['tr'] = 'Transaction Reference';
formValue['tid'] = 'Transaction id';
formValue['url'] = 'http://localhost.co/';
return formValue;
}
function readAmount() {
//const pay_amount = parseInt(req.body.amount) * 100;
return parseInt(req.body.amount) * 100;
}
function onBuyClicked() {
// if (!window.PaymentRequest) {
// console.log('Web payments are not supported in this browser.');
// return;
// }
let formValue = readSupportedInstruments();
const supportedInstruments = [
{
supportedMethods: ['https://pwp-server.appspot.com/pay-dev'],
data: formValue,
},
{
supportedMethods: ['https://tez.google.com/pay'],
data: formValue,
},
];
const details = {
total: {
label: 'Total',
amount: {
currency: 'INR',
value: readAmount(),
},
},
displayItems: [
{
label: 'Original amount',
amount: {
currency: 'INR',
value: readAmount(),
},
},
],
};
const options = {
requestShipping: false,
requestPayerName: false,
requestPayerPhone: false,
requestPayerEmail: false,
shippingType: 'shipping',
};
let request = null;
try {
//const PaymentRequest = {};
//request = PaymentRequest(supportedInstruments, details, options);
request ={supportedInstruments, details, options};
} catch (e) {
return;
}
if (!request) {
console.log('Web payments are not supported in this browser.');
return;
}
var canMakePaymentPromise = checkCanMakePayment(request);
canMakePaymentPromise
.then((result) => {
showPaymentUI(request, result);
})
.catch((err) => {
console.log('Error calling checkCanMakePayment: ' + err);
});
}
function checkCanMakePayment(request) {
//if (sessionStorage.hasOwnProperty(canMakePaymentCache)) {
//return Promise.resolve(JSON.parse(sessionStorage[canMakePaymentCache]));
//}
var canMakePaymentPromise = Promise.resolve(true);
if (request.canMakePayment) {
canMakePaymentPromise = request.canMakePayment();
}
return canMakePaymentPromise
.then((result) => {
canMakePaymentCache = result;
return result;
})
.catch((err) => {
console.log('Error calling canMakePayment: ' + err);
});
}
function showPaymentUI(request, canMakePayment) {
if (!canMakePayment) {
redirectToPlayStore();
return;
}
let paymentTimeout = window.setTimeout(function () {
window.clearTimeout(paymentTimeout);
request.abort()
.then(function () {
console.log('Payment timed out after 20 minutes.');
})
.catch(function () {
console.log('Unable to abort, user is in the process of paying.');
});
}, 20 * 60 * 1000); /* 20 minutes */
request.show()
.then(function (instrument) {
window.clearTimeout(paymentTimeout);
processResponse(instrument); // Handle response from browser.
})
.catch(function (err) {
console.log(err);
});
}
function processResponse(instrument) {
var instrumentString = instrumentToJsonString(instrument);
console.log(instrumentString);
fetch('/buy', {
method: 'POST',
headers: new Headers({ 'Content-Type': 'application/json' }),
body: instrumentString,
credentials: 'include',
})
.then(function (buyResult) {
if (buyResult.ok) {
return buyResult.json();
}
console.log('Error sending instrument to server.');
})
.then(function (buyResultJson) {
completePayment(
instrument, buyResultJson.status, buyResultJson.message);
})
.catch(function (err) {
console.log('Unable to process payment. ' + err);
});
}
function completePayment(instrument, result, msg) {
instrument.complete(result)
.then(function () {
console.log('Payment completes.');
console.log(msg);
document.getElementById('inputSection').style.display = 'none'
document.getElementById('outputSection').style.display = 'block'
document.getElementById('response').innerHTML =
JSON.stringify(instrument, undefined, 2);
})
.catch(function (err) {
console.log(err);
});
}
console.log(`in line 448....`);
function redirectToPlayStore() {
//if (confirm('Tez not installed, go to play store and install?')) {
//window.location.href = 'https://play.google.com/store/apps/details?id=com.google.android.apps.nbu.paisa.user.alpha'
//res.writeHead( "https://play.google.com/store/apps/details?id=com.google.android.apps.nbu.paisa.user.alpha" );
const response_data = axios
.post(
'https://play.google.com/store/apps/details?id=com.google.android.apps.nbu.paisa.user.alpha',
)
console.log(`in line no. 459... ${response_data}`);
return response_data;
//};
}
function instrumentToJsonString(instrument) {
var instrumentDictionary = {
methodName: instrument.methodName,
details: instrument.details,
shippingAddress: addressToJsonString(instrument.shippingAddress),
shippingOption: instrument.shippingOption,
payerName: instrument.payerName,
payerPhone: instrument.payerPhone,
payerEmail: instrument.payerEmail,
};
return JSON.stringify(instrumentDictionary, undefined, 2);
}

One signal push notification node js API

Push notification node js API using One signal
Hello guys, I've watched a tutorial to implement push notifications on flutter app project.
the code I'll show is how to set up a push notification on node js API using one signal.
I need help to know how to view the notification using One Signal API.
here is the notification service folder
notification.services.js
const { ONE_SIGNAL_API_KEY } = require('../utils/config')
const { info } = require('../utils/logger')
const sendNotification = async (data, callback) => {
const headers = {
'Content-Type': 'application/json; charset=utf-8',
Authorization: 'Basic ' + ONE_SIGNAL_API_KEY,
}
const options = {
host: 'onesignal.com',
port: 443,
path: '/api/v1/notifications',
method: 'POST',
headers: headers,
}
const https = require('https')
const req = https.request(options, res => {
res.on('data', data => {
info(JSON.parse(data))
return callback(null, JSON.parse(data))
})
})
req.on('error', e => {
return callback({
message: e,
})
})
req.write(JSON.stringify(data))
req.end()
}
here is the notification controller folder
notification.controller.js
const { ONE_SIGNAL_APP_ID } = require('../utils/config')
const notificationsService = require('../services/notifications.services')
const sendNotification = (req, res, next) => {
const message = {
app_id: ONE_SIGNAL_APP_ID,
headings: { en: 'All Devices' },
contents: { en: 'Send push notifications to all devices' },
included_segments: ['All'],
content_available: true,
small_icon: 'ic_notification_icon',
data: {
// eslint-disable-next-line quotes
PushTitle: "Porc'Ivoire",
},
}
notificationsService.sendNotification(message, (error, results) => {
if (error) {
next(error)
}
return res.status(200).send({
message: 'Success',
data: results,
})
})
}
const sendNotificationToDevice = (req, res, next) => {
var message = {
app_id: ONE_SIGNAL_APP_ID,
headings: { en: '🤑 Paiement accepté' },
contents: {
en: 'Votre paiment a été effrctué avec succès',
},
included_segments: ['included_player_ids'],
include_player_ids: req.body.devices,
content_available: true,
small_icon: 'ic_notification_icon',
data: {
// eslint-disable-next-line quotes
PushTitle: "Porc'Ivoire",
},
}
notificationsService.sendNotification(message, (error, results) => {
if (error) {
next(error)
}
return res.status(200).send({
message: 'Success',
data: results,
})
})
}
module.exports = {
sendNotification,
sendNotificationToDevice,
}

Axios POST request sending nothing with 'multipart/form-data' [React Native - Expo]

Scenario
Front end is basically a React Native (Expo) application where users can issue a report - this includes taking multiple photos and filling in some details.
Backend is just node.js, with Express & Multer.
Problem
I use Axios to send the images and form data through FormData(), however on the server side, req.body and req.files consist of nothing.
One thing here is that sending the SAME data through POSTMAN works COMPLETELY fine, the images were stored into S3 and the form details were stored in the database. It is through the app/emulator that does not work.
I've tried removing the "multipart/form-data" header and this is the output from console.log(req.body) (req.files show undefined):
{
_parts: [
[ 'userId', '1f400069-07d0-4277-a875-cbb2807750c5' ],
[
'location',
'some location'
],
[ 'description', 'Aaaaa' ],
[ 'report-images', [Object] ]
]
}
When I put the "multipart/form-data" header back this output didn't even bother showing up.
What I've Done
I've been searching for solutions for the past hours and none of them worked. Those solutions are:
Adding boundary behind the "multipart/form-data" header
Putting the type to "image/jpeg"
Trimming the file uri to "file://"
Yet none of them works
Here is my code:
React Native Frontend (Expo)
const submitReport = async () => {
setShowLoading(true);
// Validate details (location & images)
if (location === "") {
setShowLoading(false);
showToast(7002);
return;
}
if (images.length === 0) {
setShowLoading(false);
showToast(7004);
return;
}
try {
const formData = new FormData();
formData.append("userId", user.userId);
formData.append("location", location);
formData.append("description", description);
images.forEach(img => {
const trimmedURI = (Platform.OS === "android") ? img.uri : img.uri.replace("file://", "");
const fileName = trimmedURI.split("/").pop();
const media = {
name: fileName,
height: img.height,
width: img.width,
type: mime.getType(trimmedURI),
uri: trimmedURI
};
formData.append("report-images", media);
});
const response = await axios.post(`http://<my-ip-address>:3003/api/report/submit`, formData, { headers: { 'Content-Type': "application/x-www-form-urlencoded" } });
console.log(response)
setShowLoading(false);
}
catch (error) {
console.log(error);
setShowLoading(false);
showToast(9999);
}
};
Backend
// Multer-S3 Configuration
const upload = multer({
storage: multerS3({
s3: s3,
bucket: process.env.AWS_S3_BUCKET_NAME,
contentType: (req, file, callback) => {
callback(null, file.mimetype);
},
metadata: (req, file, callback) => {
callback(null, { fieldName: file.fieldname });
},
key: (req, file, callback) => {
callback(null, `${process.env.AWS_S3_REPORT_IMAGES_OBJECT_PATH}${req.body.userId}/${new Date().getTime().toString()}-${file.originalname}`)
}
}),
fileFilter: (req, file, callback) => {
// Check if file formats are valid
if (file.mimetype === "image/png" || file.mimetype === "image/jpg" || file.mimetype === "image/jpeg") {
callback(null, true);
}
else {
callback(null, false);
return callback(new Error("Image File Type Unsupported"));
}
},
});
router.post("/submit", upload.array("report-images", 3), async (req, res) => {
try {
// req -> FormData consisting of userId, location & description
// multer-s3 library will handle the uploading to S3 - no need to code here
// Details of files uploaded on S3 (Bucket, Key, etc.) will be displayed in req.files
// Analyze from Rekognition
//Add to Database code blablabla
if (result.success === true) {
res.status(200).send({ message: result.data });
}
else if (result.success === false) {
res.status(404).send({ error: ERROR_MESSAGE });
}
}
catch (error) {
console.log(error);
res.status(404).send({ error: ERROR_MESSAGE });
}
});
I'm unsure if this an Axios problem or some problem on my side.
This project is for my Final Year Project.
So after diving through search results in Google, I've found this StackOverflow post: react native post form data with object and file in it using axios
I took the answer provided by user_2738046 in my code and it worked! Combining with Ali's suggestion here is the final code that worked.
const FormData = global.FormData;
const formData = new FormData();
formData.append("userId", user.userId);
formData.append("location", location);
formData.append("description", description);
images.forEach(img => {
const trimmedURI = (Platform.OS === "android") ? img.uri : img.uri.replace("file://", "");
const fileName = trimmedURI.split("/").pop();
const media = {
name: fileName,
height: img.height,
width: img.width,
type: mime.getType(trimmedURI),
uri: trimmedURI
};
formData.append("report-images", media);
});
const response = await axios({
method: "POST",
url: `http://${<my-ip-address>}:3003/api/report/submit`,
data: formData,
headers: {
'Content-Type': 'multipart/form-data'
},
transformRequest: (data, error) => {
return formData;
}
});
// If success, clear all text fields
if (response) {
showToast(7005);
setLocation("");
setImages([]);
setDescription("");
}
setShowLoading(false);
You need to change your image uploading code with this one, you also need to install mime npm package.
const formData = new FormData();
formData.append("userId", user.userId);
formData.append("location", location);
formData.append("description", description);
const formData = new FormData();
files = files || [];
if (files.length) {
for (let index = 0; index < files.length; index++) {
const filePayload = files[index];
const file = filePayload.value;
const localUri =
Platform.OS === "android" ?
file.uri :
file.uri.replace("file://", "");
const newImageUri = localUri;
const filename = newImageUri.split("/").pop();
const media = {
name: filename,
height: file?.height,
width: file?.width,
type: mime.getType(newImageUri),
uri: localUri,
};
formData.append(filePayload.name, media);
}
}
const response = await axios.post(`http://<my-ip-address>:3003/api/report/submit`, formData, {
headers: headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
});

Why is react not posting res.json() to console?

I have tried so many thing but my react app is not recieving jsonData variable or res as a return from the node app. The app is working and printing to console on the node side but I can't get it to print onto the react side.
const submitForm = async (event) => {
event.preventDefault(); // Prevent default submission
const data2 = document.getElementById("miles").value;
const data =
"passenger_vehicle-vehicle_type_" +
carType +
"-fuel_source_" +
vehicleType +
"-engine_size_na-vehicle_age_na-vehicle_weight_na";
axios
.post(`http://localhost:8000/api/vehicle/`, { data, data2 })
.then((res) => {
const returnText = res.json();
console.log(returnText);
return res.json();
})
.then((jsonData) => {
console.log(jsonData);
return;
})
.catch((error) => {
console.log("got errr while posting data", error);
});
};
I edited out the api and api key.
var fetch = require('node-fetch');
exports.vehicle = (req, res) =>{
let status;
const { data, data2 } = res.body;
const values = {
"emission_factor": data,
"parameters": {
"distance": parseInt(data2),
"distance_unit": "mi",
},
};
fetch('https://AAAAAAAAAAAAAAAA', {
method: 'POST',
headers: {
'Authorization': 'Bearer MYAPIKEY',
'Content-Type': 'application/json'
},
body: JSON.stringify(values)
})
.then((res) => {
status = res.status;
return res.json()
})
.then((jsonData) => {
console.log(jsonData);
console.log(status);
return jsonData
})
.catch((err) => {
// handle error
console.error(err);
});
res.send(req.body);
}
Working code thanks for the help:
const submitForm = async (event) => {
event.preventDefault(); // Prevent default submission
const data2 = document.getElementById("miles").value;
const data =
"passenger_vehicle-vehicle_type_" +
carType +
"-fuel_source_" +
vehicleType +
"-engine_size_na-vehicle_age_na-vehicle_weight_na";
axios
.post(`http://localhost:8000/api/vehicle/`, { data, data2 })
.then((res) => {
console.log(res.data);
return;
})
.catch((error) => {
console.log("got err while posting data", error);
});
};
Node solution in comments.
The functions inside your then() statements need to return data e.g. then((res) => {return res.json()})
You have two problems here...
Client-side, you seem to be mixing up an Axios response with a fetch() Response. You want res.data, not res.json(). Since you've tagged this with reactjs, here is where you would set the data to a state value, eg
axios.post(...).then(res => {
setSomeState(res.data)
})
Server-side, you aren't waiting for your fetch request to complete. I'd recommend using an async function
exports.vehicle = async (req, res) => {
try {
const { data, data2 } = req.body
const values = {
"emission_factor": data,
"parameters": {
"distance": parseInt(data2),
"distance_unit": "mi",
},
}
// don't mix up the Express "res" with the fetch "response"
const response = await fetch('https://AAAAAAAAAAAAAAAA', {
method: 'POST',
headers: {
'Authorization': 'Bearer MYAPIKEY',
'Content-Type': 'application/json'
},
body: JSON.stringify(values)
})
if (!response.ok) {
throw new Error(`${response.status}: ${await response.text()}`)
}
res.json(await response.json()) // respond with the data
} catch (err) {
console.error(err)
res.status(500).send(err)
}
}

Resources