sending file to client for download - javascript

Hello I am trying to send a file from my express server to my front end to allow the user to download it when they click a button. I've created a route on the backend the sends over the byte array but I dont have the slightest idea of how to allow the user to download it.
what I'm trying to do here is allow one user to upload a file directly to my server then another user comes and downloads the file that was uploaded on a previous date.
i've gotten the upload part to work fine. now I'm just missing direction for the download part.
here is my express route being hit.
const path = require('path');
const getFile = (req, res) => {
const filePath = path.join(__dirname, '../../../', req.query.file);
console.log(filePath);
res.download(filePath);
};
here is my onClick for my frontEnd function
download(file) {
axios.get('/api/download/getFile', {
params: {
file,
},
})
.then(data =>{
console.log(data);
window.open(data.data);
})
}
and this is the error i keep on getting when i click the button
Unable to open a window with invalid URL
make sense to me because I'm not getting a url I'm getting a byte array

Try this -
window.open('/api/download/getFile?file=yourfile');

Related

Trying to get a stream link of a video file from GDRIVE API

I'm trying to get a stream link for my video files to stream it on my web app from google drive api, but its not working properly. I have double checked the docs for any errors in syntax and i can't seem to find any.
for context here is my code:
`
drive.files.get({fileId: myfileId,alt: 'media'},{responseType: 'stream'}, (err, res) => {
if (err) return console.log(`The API returned an error: ${err}`);
console.log(res)
});
`
I'm getting a passthrough object in res.data field and its giving an error of "Unknown output format: 'media' ". The file i'm trying to stream is a .mp4 file.
I have also double checked my authentication and its working fine because i was able to retrieve my folder id and file id using the api.
Am i doing anything wrong here? Any help would be appreciated.
THANKS.
Once you have authenticated the client library, you can use the following code to get a stream link for a video file stored in Google Drive
// Replace fileId with the ID of the video file you want to stream
const fileId = '1234567890';
// Get the file from Google Drive
const file = await drive.files.get({ fileId, alt: 'media' });
// Get the stream link for the file
const streamLink = file.data;

Downloading a zip file from a given path in express api + react

So I'm completely lost at this point. I have had a mixture of success and failure but I can't for the life of me get this working. So I'm building up a zip file and storing it in a folder structure that's based on uploadRequestIds and that all works fine. I'm fairly new to the node but all I want is to take the file that was built up which is completely valid and works if you open it once it's been constructed in the backend and then send that on to the client.
const prepareRequestForDownload = (dirToStoreRequestData, requestId) => {
const output = fs.createWriteStream(dirToStoreRequestData + `/Content-${requestId}.zip`);
const zip = archiver('zip', { zlib: { level: 9 } });
output.on('close', () => { console.log('archiver has been finalized.'); });
zip.on('error', (err) => { throw err; });
zip.pipe(output);
zip.directory(dirToStoreRequestData, false);
zip.finalize();
}
This is My function that builds up a zip file from all the files in a given directory and then stores it in said directory.
all I thought I would need to do is set some headers to have an attachment disposition type and create a read stream of the zip file into the res.send function and then react would be able to save the content. but that just doesn't seem to be the case. How should this be handled on both the API side from reading the zip and sending to the react side of receiving the response and the file auto-downloading/requesting a user saves the file.
This is what the temp structure looks like
There is some strategies to resolve it, all browser when you redirect to URL where extension ending with .zip, normally start downloading. What you can do is to return to your client the path for download something like that.
http://api.site.com.br/my-file.zip
and then you can use:
window.open('URL here','_blank')

download a file and pipe it to another upload url to different API

I have an image link that user can post to my app via form.
I need to download the file and make another API post request to another server.
app.post('/upload', async(req, res, next) => {
// image url is req.photo.url
const file = await require('request-promise')(req.photo.url); // i can get the response here
// now I need to post this file to another api
const options = {
method: post,
uri: 'http://sometesturl.com/api/upload',
body: {
file,
}
};
// but the file I am sending is not of type File and I am getting API error.
})
is there any way I can transform the file I downloaded into File type.
Any help would be highly appreciated. I have tried SO solutions but anything is not working.
Thanks in advance.

Send all image files from node.js to frontend

How can I send all image files from my backend nodejs server folder to my Reactjs client? I have created a web upload site where each user can signin and upload their files. So whenever a user signs-in, I want all the files he/she has uploaded to be visible on website.
res.sendFile didn't help. I found out that it does not send multiple files at once.
So far it is only sending 1 single file (console log shows all the files) that is visible on the client side.
Nodejs:
function getFiles (dir, files_){
files_ = files_ || [];
var files = fs.readdirSync(dir);
for (var i in files){
var name = dir + '/' + files[i];
if (fs.statSync(name).isDirectory()){
getFiles(name, files_);
} else {
files_.push(name);
}
}
return files_;
}
app.get('/loadit', verifyToken, (req, res) => {
var loadFiles = getFiles(__dirname + /data/);
jwt.verify(req.token, 'secretkey', (err, decoded) => {
if(err) {
res.sendStatus(403);
} else {
loadFiles.map((data1) => {
console.log(data1);
return res.sendFile(data1)
})
}
})
});
Is there any different approach for doing the same task? I also thought about sending all the images link as a json list to the frontend (reactjs) and then requesting images link from my nodejs server. I don't know if that is a good idea at all.
You can generate an archive file (like zip) on the fly at the server to download all images, e.g. with https://github.com/archiverjs/node-zip-stream to make a zip file with all images.
If you want to show all images, add an API to get a list of filenames and an other one to get a specific image file.
You can never send more than one file at a time, if you want to send all the images of the user, you should send a json array with all of his images, and on the frontend fetch them one by one.

Read file content from a form upload file

I use the following code to read the get files from the file system
The code is from a blog post called Building a File Uploader with NodeJs.
I was able to see the UI, etc when I ran my project.
I cannot use the following code since I don't have an uploads folder in my project (form.uploadDir)
app.post('/upload', function(req, res){
// create an incoming form object
var form = new formidable.IncomingForm();
// specify that we want to allow the user to upload multiple files in a single request
form.multiples = true;
// store all uploads in the /uploads directory - cannot use it
//form.uploadDir = path.join(__dirname, '/uploads');
// every time a file has been uploaded successfully,
// rename it to it's original name
form.on('file', function(field, file) {
fs.rename(file.path, path.join(form.uploadDir, file.name));
});
// log any errors that occur
form.on('error', function(err) {
console.log('An error has occurred: \n' + err);
});
// once all the files have been uploaded, send a response to the client
form.on('end', function() {
res.end('success');
});
// parse the incoming request containing the form data
form.parse(req);
});
My question is how should I get the file from the UI with the code
above? I need to get the file content from the form when I choose my file.
The application is deployed to the cloud and when I use localhost, I use the following code (which works)
const readStream = fs.createReadStream("./file.html");
...
const writeStream = sftp.createWriteStream("/index.html");
...
readStream.pipe(writeStream);
Which creates a file from the file system with the correct path and overwrites it with another file (like here index.html).
As #aedneo said, when the user choose file the file is created in the upload folder , I just needed to rename it and give the right path to the write stream method and it works!

Categories

Resources