Download CSV at client end by REST API In Nest JS - node.js

I have a array of object data from which I am creating a csv. After Generation Of CSV it should get download at client side.At client side I am using Angular and at backend it is Nest Js.
I don't want to send link to client end to download csv . it should be done by REST API

you can use this sendFile function from the Response, Exemple:
async DownloadFile(#Res() res) {
try {
....
return res.sendFile(pathfile, { root: './files' });
}catch(e) {
...
}
}
And for the frontEnd (as is in your case is Angular) you can use file-saver to download the file, to give you a hand, here is an example:
let FileSaver = require('file-saver'); // path to file-saver
....
downloadFile(data: any) { // data : WebService response
const blob = new Blob([data], { type: 'text/csv' });
FileSaver.saveAs(blob, 'filename.csv');
}

Related

Download .txt file stored on server using Hapi js

Folks, I am trying to create .txt file on submitting a form and storing it in /files folder. Then, onclick of Download button I should be able to download that file. I am using inert package from Hapi js to download the file. files folder is in root of the project.
This is my route handler for downloading
handler: async (req: Hapi.Request, h: Hapi.ResponseToolkit) => {
try {
const user = await prisma.user.findUnique({
where: {
id: Number(req.params.id)
}
});
if (user) {
h.file(`${__dirname}/../../files/certificate_2.txt`, {
mode: 'attachment',
filename: 'certificate_2.txt'
});
return h.redirect('/');
}
} catch (err) {
console.log(err);
}
But, I am not able to download the file on client side. Please help me to solve this issue

Upload image from React Native to Apollo Server not working?

I have created my backend with Nodejs and Apollo Server. I am trying to upload an image from my React Native client. Here is my backend code
Mutation: {
async singleUpload(_, { fileInput: { file, fileName } }) {
try {
const { createReadStream, filename, mimetype } = await file;
const stream = createReadStream();
const path = `./upload/${filename}`;
const tempFile = { id: 123, filename, mimetype, path };
await new Promise((resolve, reject) => {
const writeStream = createWriteStream(path);
// When the upload is fully written, resolve the promise.
writeStream.on("finish", resolve);
// If there's an error writing the file, remove the partially written file
// and reject the promise.
writeStream.on("error", (error) => {
unlink(path, () => {
reject(error);
});
});
// In node <= 13, errors are not automatically propagated between piped
// streams. If there is an error receiving the upload, destroy the write
// stream with the corresponding error.
stream.on("error", (error) => writeStream.destroy(error));
// Pipe the upload into the write stream.
stream.pipe(writeStream);
});
...then upload it to Firebase Storage
When I use Altair plugin for Firefox browser to upload image , it works fine.
Now for my React Native client, I am using apollo-upload-client lib. After a user picks image using the Image Picker plugin for React Native , I am creating a file
const file = new ReactNativeFile({
uri: image.uri,
type: image.type,
name: 'Hi there',
});
ReactNativeFile is from apollo-upload-client lib. Now when I upload it I get an error saying from my backend saying TypeError: createReadStream is not a function which I understand as there is no createReadStream parameter in my ReactNativeFile
so I decided to change my backend code to something like this
const { name, type } = await file;
console.log("Mime" + type);
const stream = fs.createReadStream(name);
fs module is from nodejs
Now when I try uploading image from Altair or from React Native , I get an error saying
[Error: ENOENT: no such file or directory,
Due to my lack of knowledge of backend I am not sure what is causing the issue.
I think if I try uploading it from ReactJS instead of React Native, my code might work for the backend.
But the image picker for browser and native mobile are very much different and I have not tried doing with ReactJS for now
I am following this article https://moonhighway.com/how-the-upload-scalar-works for my backend code

How do I create a file in express and node on my server and then download it to my client. I am using NextJS for my frontend and backend

How do I create a file in express and node on my server and then download it to my client. I am using NextJS for my frontend and backend. I am confused on how I would download the file on the front end after the file is created on the root of the server folder. Since I am using React for my frontend whenever I try to visit that filepath it tries to take me to a page instead of the file
Here is what I have in my express route in node
var xls = json2xls(json, {
fields
});
// If there isn't a folder called /temp in the
// root folder it creates one
if (!fs.existsSync('./temp')) {
fs.mkdirSync('./temp');
}
const fileName = `temp/${req.user.first_name}${req.body._id + Date.now()}.xlsx`
// fs.writeFileSync(fileName, xls, 'binary');
fs.writeFile(fileName, xls, 'binary', function (err, result) {
if (err) {
return console.log(err);
}
console.log(result, 'this is result')
});
Here is what I have on my frontend
axios.post('api/download',payload)
.then(res => {
const link = document.createElement('a');
link.href = res.data.url;
link.download
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
})
.catch(err => {
throw err
})
Can you make request with GET on api, and.
Make request with GET.
Make temp directory to be static resources directory:
app.use(express.static('temp')); // app is your express instance.
// Maybe you have to correct temp's path
Response the post request with file url data
fs.writeFile(fileName, xls, 'binary', function (err, result) {
if (err) {
return console.log(err);
res.status(500).json({err});
}
console.log(result, 'this is result');
res.json({url: 'http://localhost:8080/temp/' + fileName}); // res is response object of you router handler.
// Maybe you have correct the server address
});
On other way, you can send the xls binary direct to client, in the client you create a BLOB object from the response, then create download link for the blob object.

Upload images into a file server and store the url to the image using nodejs

I am implementing a web app using MEAN Stack and Angular 6. There I want to submit a form with file upload. '.png' files should be uploaded.
I want to save the file in a different file server and send the url to the image.Currently I upload files into a folder in my project and save the image in db (I used ng2fileupload and multer for that.). Then it saves like this.
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAV4AAAFUCAYAAABssFR8AAAK..."
But I want to save the image url and the image should be retrived by the url. Does anyone can explain a proper method for that?
I faced the same problem a month ago and find out a solution to this problem. Though I haven't used multer in the app.
From my frontend, I will be sending an object to Node API endpoint /event which will look like:-
let img = {
content: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...",
filename: 'yourfile.png'
}
At the backend, I'm using Cloudinary to store my images (Its free plan allows 10GB storage) and returns secure https URLs. So install it using npm i cloudinary and require in your api.js file.
And add the below configuration
cloudinary.config({
cloud_name: 'yourapp',
api_key: 'YOUR_KEY',
api_secret: 'YOUR_SECRET_KEY'
});
Last Step:- (Not so optimized code)
Let say I have an event Schema which has images array, where I'll be storing the URLs returned by cloudinary.
app.post('/event', (req, res) => {
try {
if (req.body.images.length > 0) {
// Creating new Event instance
const event = new Event({
images: [],
});
// Looping over every image coming in the request object from frontend
req.body.images.forEach((img) => {
const base64Data = img.content.split(',')[1];
// Writing the images in upload folder for time being
fs.writeFileSync(`./uploads/${img.filename}`, base64Data, 'base64', (err) => {
if (err) {
throw err;
}
});
/* Now that image is saved in upload folder, Cloudnary picks
the image from upload folder and store it at their cloud space.*/
cloudinary.uploader.upload(`./uploads/${img.filename}`, async (result) => {
// Cloudnary returns id & URL of the image which is pushed into the event.images array.
event.images.push({
id: result.public_id,
url: result.secure_url
});
// Once image is pushed into the array, I'm removing it from my server's upload folder using unlinkSync function
fs.unlinkSync(`./uploads/${img.filename}`);
// When all the images are uploaded then I'm sending back the response
if (req.body.images.length === event.images.length) {
await event.save();
res.send({
event,
msg: 'Event created successfully'
});
}
});
});
}
} catch (e) {
res.status(400).send(e);
}
});
P.S. Go ahead and suggest some optimization solution for this code here

Sending File(Any type) from node server and receving it in html

I want to send a file from Node server using get Method and want to receive it on Angular2 client side
Here is my Api for getting a file:
File Receiver Api Using Node Express
function getUserFileByEmail(req, res) {
UserCv.findOne({ emailAddress: req.params.emailAddress }, (err, usercv) => {
if (err) {
return res.send(err);
}
const filePath = path.join('E:/Work/node-portal/uploads', usercv.file);
console.log(filePath);//this is printing the exact file name along with extension that i want to receive at cliend end
usercv.file = filePath;
res.sendFile(filePath);
});
}
and in client side my code is:
FileReceiver request using angular2
getfile() {
return this.http.get(`${this._getfile}/${user.emailAddress}`, options)
.map(res=> (<Response>res).blob())
.catch(this.handleError);
}
By doing this i am receiving an error that is:
"The request body isn't either a blob or an array buffer"
So any one knows what exactly I am doing wrong in my server side or client side file

Resources