Problem with form-data request with node.JS - form-data

Good morning. I will try to explains my problems. So i must create the back-side of a web site, and i can't retrieve information of a form-data request. The request contains a object and an image but when i do console.log(req.body.key)i obtain an wonderful undefined.
Below the source code of the application. The front is created with Angular and the back with Node.JS
Back-end:
+app.js
const express = require("express") ,
app = express () ,
moongoose = require("mongoose") ,
bodyParser = require("body-parser") ,
path = require("path") ,
userRoute = require("./routage/user") ,
sauceRoute = require("./routage/sauces") ;
moongoose.connect("mongodb://localhost/Pekito" , {
useNewUrlParser: true ,
useUnifiedTopology: true
})
.then(() => {console.log("Connecte a mongo")})
.catch((error) => {console.log(error)}) ;
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use("/api/auth/" , userRoute) ;
app.use("/api/sauces/" , sauceRoute) ;
module.exports = app ;
+routes
exports.createSauces = (req , res , next) => {
console.log(req.body.sauce) ; => undefined
}
the front-end:
createSauce(sauce: Sauce, image: File) {
return new Promise((resolve, reject) => {
const formData = new FormData();
formData.append('sauce', JSON.stringify(sauce));
formData.append('image', image);
this.http.post('http://localhost:3000/api/sauces', formData).subscribe(
(response: { message: string }) => {
resolve(response);
},
(error) => {
reject(error);
}
);
});
}
So if you can explain me my error i will be very grateful to you
NB: excuse for my english, i'am a french student)

FormData objects send multipart requests.
Your have body parsers for URL encoded and JSON encoded requests.
You need to add a body parser capable of handling multipart.
See the documentation for the body-parser module:
This does not handle multipart bodies, due to their complex and typically large nature. For multipart bodies, you may be interested in the following modules:
busboy and connect-busboy
multiparty and connect-multiparty
formidable
multer
Pick one of those modules and follow its instructions.

Related

Receive & Respond to Twilio Text Message with Node js express graphql

I followed the Twilio instructions to setup receive & respond to a text message as in the URL below which uses a Rest Post. It works. Great.
app.post('/sms', (req, res) => {
// Start our TwiML response.
const twiml = new MessagingResponse();
// Add a text message.
const msg = twiml.message('Check out this sweet owl!');
// Add a picture message.
msg.media('https://demo.twilio.com/owl.png');
res.writeHead(200, {'Content-Type': 'text/xml'});
res.end(twiml.toString());
});
I then wanted to convert the REST POST to a graphql POST to be consistent with my code base. I set it up, and my graphql POST responds with the following format which is not xml (which I believe Twilio requires) but json as per graphql. Thus, I can see the response move through the system but Twilio registers an error. If I'm correct, is there a way for Twilio to process the graphql json response or for me to adjust graphql to return xml rather than json (as below)?
My latest graphql attempt wraps the rest post in a graphql query as such.
sms: async () => {
// console.log(request, response);
const { MessagingResponse } = require("twilio").twiml;
const twiml = new MessagingResponse();
twiml.message("The Robots are coming! Head for the hills!");
let test = "";
return axios({
method: "post",
url: "https://2b52-98-38-82-19.ngrok.io/sms",
responseType: 'text/xml'
})
.then(res => test = res.data)
// .then(function (response) {
// console.log('axios response =', response);
// return twiml.toString();
// })
.catch(function (error) {
console.log(error);
});
}
}
returning the following via Apollo Sandbox and/or insomnia.
{
"data": {
"sms": "<?xml version="1.0" encoding="UTF-8"?><Response><Message>The Robots are coming! Head for the hills POST POST!</Message></Response>"
}
}

Nextjs api resolving before form.parse completes so i cant send response back

I am trying to send an image to Next.js api and then use that image to upload to db.
I am using :
const body = new FormData();
body.append("file", prewiedPP);
const response = await fetch("/api/send-pp-to-server", {
method: "POST",
body ,
headers: {
iext: iExt,
name: cCtx.userDetail ,
},
});
Then in the api :
async function handler(req, res) {
if (req.method === "POST") {
console.log("In");
const form = new formidable.IncomingForm();
form.parse(req,
async (err, fields, files) =>
{
// console.log(req.headers.iext);
// console.log(req.headers.name);
const fdata = fs.readFileSync(files.file.filepath);
await delUserPP(req.headers.name , req.headers.iext);
await setUserPP(
fdata ,
req.headers.name ,
req.headers.iext ,
files.file.mimetype
);
fs.unlinkSync(files.file.filepath);
return;
});
console.log("out");
}
}
export default handler;
The callback function in the from.parse happens after the handler already resolved.
Is there anyway to make the api call only resolve after the setUserPP function is done?
I want to send a response back to the client but the api script finishes to "fast" and before the callback in form.parse runs.
Thanks

react can't get restController response

I have tried to use restController generate file byte array but when i return it to react , react didn't get the byte array. front-end is using react , back-end is using spring restController and i use Http to communication both front and back. is it any wrong in my code? Thank you for your helping.
restController:
String fileName = DateUtility.dateToStr(new Date(), DateUtility.YYYYMMDD_HHMMSS) + " - "
+ reportNmaeByType.get(exportParam.getReportType()) + ".xls";
HttpHeaders headers = new HttpHeaders();
headers.setContentDispositionFormData("attachment", fileName);
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
return new ResponseEntity<>(excelByte, HttpStatus.OK);
react:
createExcelFile(){
var params = {
reportResultList: this.state.reportResult,
reportType: getReportSelector().state.selectedReportType,
selectColumnMap: this.state.selectColumn,
selectCusColumnMap: this.state.selectCusColumn
}
fetch("http://localhost:8080/mark-web/file/createExcel", {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(params)
}).then(res => {
if (res.ok) {
console.log(res)
console.log(this)
console.log('create excel success!!')
} else {
console.log('create excel Fail!!')
}
})
}
response:
enter image description here
Update 2018/09/16:
I have added some code in react function and it finally could download excel file but the file is broken. i have checked the blob object in response. it shows blob is json object. is it because i didn't decode to the blob object?
React:
}).then(res => {
if(!res.ok){
console.log("Failed To Download File")
}else{
return res.blob()
}
}).then(blob => {
console.log(blob)
let url = URL.createObjectURL(blob)
console.log(url)
var downloadAnchorNode = document.createElement('a')
downloadAnchorNode.setAttribute("href", url)
downloadAnchorNode.setAttribute("download", "excel" + ".xls")
downloadAnchorNode.click()
downloadAnchorNode.remove()
})
response:
enter image description here
So, from your network graph, it looks like your request is completing as expected, but you are just unable to derive the ByteArray from the response.
With normal requests which return a JSON or XML for e.x. you can read them in one go, as they are part of the body. In your case however, your body contains a Stream. You will thus have to handle reading that stream on your own.
You can do that with response.blob() :
The blob() method reads the stream to completion and returns a Blob object. You can then use this blob object to embed an image or download the file. For all intent and purposes, I would recommend using this. Unless you are dealing with huge files (>500 MB), it should suffice your needs.
For example:
fetch("http://localhost:8080/mark-web/file/createExcel", {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(params)
}).then(res => {
if (!res.ok) {
throw new Error(res.statusText);
} else {
return res.blob()
}
}).then(blob => {// do your thing})
.catch(err => console.log(error))
Or
You can use the experimental ReadableStream interface for a more granular control over what you want to do with it.

How to get each http body updates on angular Http request?

I'm using an express api (my back-end) and an angular app (my front-end).
One express js end point (let's call it '/foo') is processing a lot of files,
i send data using res.write() after each treatment so the http response body is update.
I would like to get this update on my angular app.
I was using ajax in a previous version and it worked fine with ajax call :
xhrFields: {
// Getting on progress streaming response
onprogress: function(e)
{
var progressResponse;
var response = e.currentTarget.response;
if(lastResponseLength === false)
{
progressResponse = response;
lastResponseLength = response.length;
}
else
{
progressResponse = response.substring(lastResponseLength);
lastResponseLength = response.length;
}
actualResponse += progressResponse
}
Unfortunatly i found nothing to get partial http body. I tried to use 'reportProgress' Parameter but it's not working.
For some more context my front-end angular code:
service.ts :
setHolidaysDirectory(holidaysKey: string, path: string): Observable<Object>{
const setHolidayDirectoryStreamHttpRequest =
new HttpRequest('POST', 'http://localhost:8089/holidays/pictures/edit', { 'key': holidaysKey,
'path': path
}, {headers: this._httpHeaders, reportProgress: true, responseType: 'text'});
// pipe stream answer
return this._http.request(setHolidayDirectoryStreamHttpRequest);
}
and my component just call the service and subscribe :
this._holidaysService
.setHolidaysDirectory(key, finalHolidaysForm.path)
.subscribe((stream) => {
console.log('new answer');
console.log(stream);
}, error => console.log(error));
But unfortunatly i got empty answer and all the http body is recovered after res.end() (server side)
Can anyone help pls !
Thank a lot !

Difficulty creating a functional Angular2 post

I'm trying to send a post request to another service (a Spring application), an authentication, but I'm having trouble constructing a functional Angular2 post request at all. I'm using this video for reference, which is pretty new, so I assume the information still valid. I'm also able to execute a get request with no problems.
Here's my post request:
export class LogIn {
authUser: string;
authPass: string;
token: any;
constructor(private _http:Http){}
onSubmit() {
var header = new Headers()
var json = JSON.stringify({ user: this.authUser, password: this.authPass })
var params2 = 'user=' + this.authUser + '&password=' + this.authPass
var params = "json=" + json
header.append('Content-Type', 'application/x-www-form-urlencoded')
this._http.post("http://validate.jsontest.com", params, {
headers: header
}).map(res => res.json())
.subscribe(
data => this.token = JSON.stringify(data),
err => console.error(err),
() => console.log('done')
);
console.log(this.token);
}
}
The info is being correctly taken from a form, I tested it a couple of times to make sure. I am also using two different ways to build the json (params and params2). When I try to send the request to http://validate.jsontest.com, the console prints undefined where this.token should be. When I try to send the request to the Spring application, I get an error on that side:
Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported
Does anyone know what I'm doing wrong?
In fact you need to use the GET method to do that:
var json = JSON.stringify({
user: this.authUser, password: this.authPass
});
var params = new URLSearchParams();
params.set('json', json);
this._http.get("http://validate.jsontest.com", {
search: params
}).map(res => res.json());
See this plunkr: http://plnkr.co/edit/fAHPp49vFZJ8OuPC1043?p=preview.

Resources