How to convert buffer to file to download on react side - node.js

I am using https://www.npmjs.com/package/convert-html-to-pdf to convert html to pdf in nodejs. I have a react frontend and nodejs backend. I want to convert the buffer to a file that people can download on the react side. How can I do this? I don't want to save the file on my servers.

We can set header Content-disposition attachment to indicate that the response is a downloadable file.
Backend: example in Express
const htmlToPDF = new HTMLToPDF(`
<div>Hello world</div>
`);
const buffer = await htmlToPDF.convert();
res.set("Content-Disposition", `attachment; filename="test.pdf"`);
res.set("Content-Type", "application/pdf");
res.send(buffer);
Frontend: example in React
const submit = () => {
window.open("http://localhost:8000"); // Your endpoint here
};
return (
<button onClick={submit}>Download</button>
);
If the endpoint is POST method then window.open won't work. We have to use a form:
<form action="http://localhost:8000" method="POST">
<button type="submit">Download</button>
</form>

Related

Creating Video and Audio Upload Feature

I’m in the beginning stages of planning out my final Capstone project for my Bootcamp.
Two of the features I would like to include are the ability to upload:
Audio
Video
I will be using React.JS for Front-End and Python / Django for server side.
Any suggestions or recommendations for how to approach these upload features?
I’m currently beginning researching how to do this.
you can use html tag input on react
const [file , setFile] = useState();
<input
type="file"
id="fileInput"
onChange={(e) => setFile(e.target.files[0])}
/>
after that you can use FormData() to create file format then send file to api
const data = new FormData();
const filename = username + "_" + file.name;
data.append("name", filename);
data.append("file", file);
try {
api.uploadFile(data);
} catch (error) {
console.log(error);
}
at backend ( django ) I don't know how to handle file requset but you can find it easily . At react side you can use codes at top .

Why React doesn't upload image to server?

I have an app using react and express on the backend and multer to manage the upload. The server side is running properly when I make tests using postman, but if trait to send an image from react the result is unexpected. In that case the file doesn't appear in the uploads folder, however with postman is immediatly.
UploadPage,jsx
const { register, handleSubmit } = useForm();
const onSubmit = async (data) => {
const formData = new FormData();
formData.append('petimage', data.petimage);
try {
const res = await axios.post('/api/petregister', formData);
console.log(res)
} catch (error) {
setError(error.response.data.error);
setTimeout(() => {
setError("");
}, 5000);
}
}
return (
<Container className="mt-5">
<Form onSubmit={handleSubmit(onSubmit)}>
<Form.Group controlId="formFile" className="mb-3">
<Form.Label>Imagen de tu Mascota</Form.Label>
<Form.Control type="file"
label="Select image"
name="petimage"
{...register("petimage")}
/>
</Form.Group>
<Button variant="primary" type="submit">
Submit
</Button>
</Form>
</Container>
Google Response
The fields with name petimage are the same that I expecified in the backend and used these in the postman tests.
Edit
const store = require('../middlewares/multer');
route.post('/petregister', store.array('petimage', 12), petregister);
The last section of code is the route that is linked with the multer midleware asigned to ssave the images.
When you are making a API call to the backend, it will upload the image to the specific folder that you are defining in the backend like :
const multer = require('multer');
const upload = multer({ dest: 'folder path' });
I think you are getting results unexpected because the name for the image you are giving in formData formData.append('petimage', data.petimage); i.e petimage, it should be the same in the multer fileupload method. You haven't shared the backend code. So, I'm hoping that it may be like this:
var fileUpload = upload.single('petimage'); when the name is the same it will work fine.
If the image is of big size, you can compress it. Please visit this link, it will help you for sure.
https://dev.to/franciscomendes10866/image-compression-with-node-js-4d7h
You can try:
Remove
formData.append('petimage', data.petimage);
and use instead
data.petimage.forEach(pet => formData.append("petimage", pet))
The solution was trait the image as an object. The code is the next:
Object.values(data.petimage).forEach(pet => formData.append('petimage', pet))
Then it worked as expected.

Angular 5 - FileUpload not working

Edit: Fixed. I had to add this to my response:
.subscribe(data =>{
console.log('data is here: ', data);
});
I have read through whole bunch of articles on this one, but cannot get it to working.
Environment: Angular 5, NodeJS backend with Express. Using Express-FileUpload to upload the file.
I tried my API with this simple HTML:
<html>
<body>
<form ref='uploadForm'
id='uploadForm'
action='http://192.168.1.20:8275/api/upload'
method='post'
encType="multipart/form-data">
<input type="file" name="sampleFile" />
<input type='submit' value='Upload!' />
</form>
</body>
</html>
Figured that my API is working fine, the API End point receives the request from HTML just fine. Now, this is what I am trying to do Angular:
let body = new FormData();
body.append("file", file, 'thefilename');
let options: RequestOptions = new RequestOptions();
options.headers = new Headers();
let response: Observable<Response> = this.http.post('http://192.168.1.20:8275/api/upload', body, options); //code just breaks here and exists silently
response.map(json =>{
console.log('gotcha')
}),err =>{
console.log('error: ', err);
};
Angular code doesn't work. After the POST call, it breaks and exits silently. Nothing in console, no error. And I am unable to figure out why? I read through articles, and found we don't have to supply a content type to make it work. I tried that too but no luck. What can be the issue?

Uploading a file and sending it to the backend with React and Node

I need to upload a file in react and send it to the Node backend.
Since I never worked with uploading and sending files before, this is a little troubling for me.
So far I found this:
// this creates a React component that can be used in other components or
// used directly on the page with React.renderComponent
var FileForm = React.createClass({
// since we are starting off without any data, there is no initial value
getInitialState: function() {
return {
data_uri: null,
};
},
// prevent form from submitting; we are going to capture the file contents
handleSubmit: function(e) {
e.preventDefault();
},
// when a file is passed to the input field, retrieve the contents as a
// base64-encoded data URI and save it to the component's state
handleFile: function(e) {
var self = this;
var reader = new FileReader();
var file = e.target.files[0];
reader.onload = function(upload) {
self.setState({
data_uri: upload.target.result,
});
}
reader.readAsDataURL(file);
},
// return the structure to display and bind the onChange, onSubmit handlers
render: function() {
// since JSX is case sensitive, be sure to use 'encType'
return (
<form onSubmit={this.handleSubmit} encType="multipart/form-data">
<input type="file" onChange={this.handleFile} />
</form>
);
},
});
Source: https://fitacular.com/blog/react/2014/06/23/react-file-upload-base64/
But now I basically just end up with some sort of string. But I need to send that file via REST to my Express backend, which needs to save that file in CouchDB.
What is the best/easiest way to accomplish that?
If you are using body-parser, know that it handles json and url encoded forms, not multipart data !
You should use an other module.
For more infos, give a look at : File uploading with Express 4.0: req.files undefined

Get ng-model values on POST to Express.js endpoint

I am creating a Node.js application with AngularJS.
I want to make a simple POST, using Angular. This POST should post a couple of values to my server, where I can see them using console.log.
In my HTML code, I build it with the ng-model and a button that has a ng-click.
I can tell my Node.js server is being hit, as it outputs the post called in the console.
However, I have been trying to read about how to read the POST values, but I haven't found a solution.
How would I modify my code to read serialKey and gameTitle in my Express.js endpoint?
My HTML code:
<div class="input-group" ng-controller="CreateController">
<p>Serial key:<br/>
<input class="form-control" ng-model="serialKey" />
</p>
<p>Game:<br/>
<input class="form-control" ng-model="gameTitle" />
</p>
<span class="input-group-btn">
<button class="btn btn-default"
ng-click="postNewIsbn(serialKey,gameTitle)">Add</button>
</span>
</div>
Angular controller code:
app.controller('CreateController',function($scope, $http) {
var url = '/api/serials';
$scope.postNewIsbn = function(serial, game) {
$http.post(url, {
serial: serial,
gametitle: game
})
.success(function (data) {
$scope.data.status = 'success';
})
.error(function(error) {
$scope.data.error = error;
});
};
});
Express.js endpoint
app.post('/api/serials',function(req,res){
console.log(req.body);
console.log('post called');
});
It appears to be the problem of setting content-type header. In your angular application you can set defaultHeaders for your post request just after you initialize the module or in your config function with this line
$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
Do remember to inject the $httpProvider dependency whereever you setting this header
UPDATE
It may be the case that you need to configure your express in order to use the bodyParser with this line:
app.use(express.bodyParser());
req.param(name)
When attempting to retrieve data passed with the request, the req.param() function checks the following in order to find the parameter:
req.params
req.body
req.query
See the docs here.
Also, try explicitly setting the content-type header in the POST request to "application/json".

Resources