Send an Object with Blobs in it to server - javascript

I have a data object containing strings, booleans, arrays, objects and even Blobs like this:
Now I want to send this object to my Node.js server...
Using traditional fetch API or Ajax I'm unable to send the blobs and they appear like an empty object server side!
I tried to use fetch API even using FormData approach like:
Client:
const fd = new FormData();
fd.append("upload", data); // data is the object to send
fetch('/mother/new-card', {
method: 'post',
body: fd,
})
Server:
controller side:
router.post('/new-card', newCard);
function newCard(req, res) {
motherService.newCard(req)
.then(result => res.json(result))
.catch(err => {
console.log(err);
res.json(err)
});
}
Service side:
async function newCard(req) {
console.log('req.body', req.body);
return { success: req.body }
}
I usually get undefined trying above methods ...
Is there any valid way to send an object with blobs in it?

Related

Trouble understanding loading json with promises express

In my nodeJs app I create a post request;
const express = require('express');
const app = express();
app.listen(80, () => console.log('Listening at 80'));
var movies = require("G:/path/to/json/movienames.json");
app.use(express.json({ limit: '1mb'}));
app.post('/movies', (request, response) => {
console.log('I got a request!');
console.log(request.body);
response.json(
movies
);
});
Now in my Javascript file i need to receive the promise and get the data with .then with a function call to convert it to json. Then it sends the data. I guess?
const postMovieLoad = {"Movies has been loaded": "True"};
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(postMovieLoad)
};
moviesJson = fetch('/movies', {
method: "POST", // "GET/POST"
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(postMovieLoad)
})
.then(moviesJson => moviesJson.json())
.then(moviesJson => {
Json = {//Json copied directly from file};
console.log(Json === moviesJson); //logs false
console.log(Json); // logs {movies: Array(193)}
console.log(moviesJson); // logs {movies: Array(193)}
console.log(typeof Json, typeof moviesJson); //logs object object
}).catch(error => console.error('Error', error))
I fetch the promise. The syntax is confusing me alot here. I'm a little unsure about the .then function stringed together. I think its like a handshake between the server and the client.
What is really stumping me though, is why the file has been modified and why? Both are json objects, both have the same contents. I just want to get the json object to be assigned to a variable client side from server side.
When you do that (a === b), you are comparing that a and b are the same object, that is, the same reference in memory, since the objects in javascript are references, in your case a and b do not have the same memory address, then you will not be able to do it that way JSON.stringify (a) == JSON.stringify (b) could help, you could add a trim to be safer since there you convert it to string and the comparison is not by reference, its by characters length and order

My sent data using axios is returned in config, not data

I am building my web app on NextJS NodeJS and Express, I am running two servers on localhost 3000 for next and 9000 for express.
I have a form with two input fields and I am sending the state with axios post to the url with data, on the server-side I am receiving that request and sending back the same received data as a response.
I get the response from server with data: success and my data in config.data
Why is my data in config data and how can I get it out from this JSON so I can pass it to a variable.
As for grabbing the data from the config.data, I have tried for loops but they either push 56 elements of 56 numbers to the empty array or don't do nothing.
Client side:
state = {
bank_name: '',
account_number: ''
}
...
onSubmit = (e) => {
e.preventDefault()
axios.post('http://localhost:9000/api/bank', {
bankName: this.state.bank_name,
accNumber: this.state.account_number
})
.then(res => {
console.log(res)
}).catch(err => console.log(err))
}
Server side:
router.post('/', (req, res) => {
const {reqData} = req;
res.send(reqData);
})
Console log from client side ( console.log(res) ):
{
config: {
url: "http://localhost:9000/api/bank",
method: "post",
data: '{"bankName":"some new bank","accNumber":"39276542934235"}'
},
data: "success",
headers: "...",
request: "...",
status: 200,
statusText: "OK",
__proto__: Object
}
...
When I target res.config.data.bankName I get undefined.
I believe this has to do with the server response being as it is, or not parsing the data server receives in the first place, or it is due to promises.
Any input would be helpful, thanks
That res.config.data is string so parse it first JSON.parse(res.config.data) and then access the bankName.
Also you must be using body-parser at the express end. And so post data resides in req.body you should send that back not the whole req IMO.
Express:
router.post('/', (req, res) => {
const reqData = req.body;
return res.send(reqData);
});
Axios: (returned data should be in res.data)
axios.post('http://localhost:9000/api/bank', {
bankName: this.state.bank_name,
accNumber: this.state.account_number
})
.then(res => {
console.log(res.data);
}).catch(err => console.log(err))
}

How to post object using fetch with form-data in React?

I want to send a file to my express app as backend. My problem is that my body is send as type application/json and I want to send this as a form-data and later upload this file using multer -> https://github.com/expressjs/multer
I don't know how to prepare fetch call to get it later in express.
fetch('/api/data', {
method: 'POST',
headers: {
Accept: 'application/form-data',
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
})
.then((resp) => resp.json())
.then((data) => console.log(data));
When I want to log req.file in api breakpoint I'm getting undefined.
app.post('/api/data', upload.single('cv'), (req, res) => {
console.log(req.body);
console.log(req.file);
res.send({ name: 'Hello world!' });
});
I store react data from form using hooks and this object looks like this:
{
name: 'test',
surname: 'test2',
cv: 'C:\\fakepath\\Babel error.png'
}
You need to build your request body using the FormData API.
The FormData interface provides a way to easily construct a set of key/value pairs representing form fields and their values, which can then be easily sent using the XMLHttpRequest.send() method. It uses the same format a form would use if the encoding type were set to "multipart/form-data".
const myFile = document.querySelector("input[type=file]").files[0];
const data = new FormData();
data.append("myFile", myFile);
data.append("otherStuff", "stuff from a text input");
fetch(target, {
method: "POST",
body: data
});

Can I do multiple fetch in a single component in react?

I am using react as my frontend and express.js as my backend. I new to both framework. I have a component called Papers and I am trying to first upload some documents to the backend server through fetch post then perform some operation on the server side and then I am trying to get back the result from server in the same handler. My code for the handler looks like this:
handleDrop(files) {
var data = new FormData();
alert((files[0]) instanceof File);
files.forEach((file, index) => {
data.append('file' + index, file);
});
fetch('/file_upload', {
method: 'POST',
body: data
});
// the second fetch would crash the app.
/*fetch('/file_upload').then(function(data){
return data.json();
}).then( json => {
this.setState({
papers: json
});
console.log(json);
});*/
}
My express backend code for the get method is :
app.get('/file_upload', function(req, res){
// testing
res.send({name:"lol"});
});
The problem right now is the second fetch would crash the express app. Since I am new to react and express, can someone please give me some hints if I am doing this in the right way? Thanks!
link to server code: https://github.com/kaiwenshi/learn-webpack/blob/master/src/server/index.js
Express code should look like this if you want to do a POST:
app.post('/file_upload', function(req, res){
// testing
res.send({name:"lol"});
});
And you only need to do one call of fetch. The response ({name: 'lol'}) will be in the promise:
handleDrop(files) {
var data = new FormData();
alert((files[0]) instanceof File);
files.forEach((file, index) => {
data.append('file' + index, file);
});
fetch('/file_upload', {
method: 'POST',
body: data
}).then(function(data){
return data.json();
}).then( json => {
this.setState({
papers: json
});
console.log(json); // logs {name: 'lol'}
});
}

How do I send a file with node.js request module?

I am trying to use an API to update a list on another server using node.js. For my last step, I need to send a POST that contains a csv file. In the API, they list under FormData that I need a Key called file and a Value of Binary Upload, then the body of the request should be made of listname: name and file: FileUpload.
function addList(token, path, callback) {
//Define FormData and fs
var FormData = require('form-data');
var fs = require('fs');
//Define request headers.
headers = {
'X-Gatekeeper-SessionToken': token,
'Accept': 'application/json',
'Content-Type': 'multipart/form-data'
};
//Build request.
options = {
method: 'POST',
uri: '{URL given by API}',
json: true,
headers: headers
};
//Make http request.
req(
options,
function (error, response, body) {
//Error handling.
if (error) { callback(new Error('Something bad happened')); }
json = JSON.parse(JSON.stringify(response));
callback.call(json);
}
);
//Attempt to create form and send through request
var form = new FormData();
form.append('listname', 'TEST LIST');
form.append('file', fs.createReadStream(path, { encoding: 'binary' }));
form.pipe(req);};
I am a veteran of front end javascript for html and css, but this is my first adventure with backend node.js. The error I keep getting is: TypeError: dest.on is not a function
From what I can tell, this has to do with the way I used form.pipe(req) but I can't find documentation telling me the appropriate usage. If you don't have a direct answer, a finger pointing toward the right documentation would be appreciated.
The issue is you're not passing the request instance into your pipe call, you're passing the request module itself. Take a reference to the return value of your req(...) call and pass this instead i.e.
//Make http request.
const reqInst = req(
options,
function (error, response, body) {
//Error handling.
if (error) { callback(new Error('Something bad happened')); }
json = JSON.parse(JSON.stringify(response));
callback.call(json);
}
);
//Attempt to create form and send through request
var form = new FormData();
...
form.pipe(reqInst);
This line:
.pipe(fileinclude)
Should be this:
.pipe(fileinclude())
from
why am i getting this error? dest.on is not a function - using gulp-file-include

Categories