MongoDB GridFS uploads zero-length file when using Node and request - node.js

I'm trying to save a file from a URL to a Mongo GridFS file. I'm using the request npm module, and the official mongo driver.
This is my code:
function retrieveAttachments(NormalizedMessage) {
NormalizedMessage.attachments.forEach(
function (currentAttachment) {
var bucket = new GridFSBucket(db);
var httpRequestStream = require('request');
httpRequestStream.get(currentAttachment.url)
.on('error', function (err) {
console.log(err);
})
.pipe(bucket.openUploadStream('dsa'));
}
);
}
"db" is obtained from MongoClient.connect, and GridFSBucket = require('mongodb').GridFSBucket;
The problem I have is that the file is inserted in mongo (I can see it in the fs.files collection), but it's length is zero.
If i also add a .on('finish') event to the upload stream, it gets called.
If I replace bucket.openUploadStream('dsa') with fs.createWriteStream('someFile'), the HTTP request is saved to someFile in the local filesystem.
If I replace httpRequestStream.get(currentAttachment.url) with fs.createReadStream("test.jpg"), the file test.jpg is successfully uploaded to GridFS.

Related

Create a Blob for Video in NodeJs18 and Use it on Client Side

Learning NodeJs and Blob, and I Try to Create a Blob from a Video File in NodeJS. And send this in a Json file to my Client. Data will be Fetch inside GetStaticProps in NextJS.
Here is What I Created in NodeJS Server :
const fileBuffer = fs.readFileSync(filePath); // Path is something like example.com/video.mp4
const blob = new Blob([fileBuffer], { type: 'video/mp4' });
blobUrl = URL.createObjectURL(blob); // Return blob:nodedata:c3b1baf2-fba8-404f-8d3c-a1184a3a6db2
It retrun this :
blob:nodedata:c3b1baf2-fba8-404f-8d3c-a1184a3a6db2
But How can I use it in Client ? <video src="blob:nodedat..." is not Working, so I am doing something wrong for sure
Can you help me uderstand what is wrong ?

Storing and downloading pdf files from mongoDB using Node.js

I am using NodeJs, mongoose, ejs
I want the user to be able to upload his CV (Less the 16 MB) as a pdf file, then the admin to be able to download the pdf or view the CV on the website.
I did the upload part where I stored the cv like this in the database (which might be a wrong way):
cv: Object {
fileName: "Test Results All in testing-homework.pdf"
filePath: "cvs\1650985306448-.pdf"
fileType: "application/pdf"
}
and the pdf file is stored in the "/cvs" folder after upload.
I'm seeking a way to be able to download/view the pdf file from the database.
I will suggest you to use GridFs from mongodb.
refer:https://www.mongodb.com/docs/drivers/node/current/fundamentals/gridfs/
To Download from DB
bucket.openDownloadStreamByName('your_file_name').
pipe(fs.createWriteStream('./desired_name_of_output_file'));
Some of the Basic Upload and Download Operations using GridFs in MongoDB
const mongoUrl='mongodb://127.0.0.1:27017/db'
const mongodb = require('mongodb');
const fs = require('node:fs');
const client = new mongodb.MongoClient(mongoUrl)
const db = client.db('db');
Create Bucket with user-defined name
const bucket = new mongodb.GridFSBucket(db,{bucketName:'name_of_bucket' });
Upload to DB
fs.createReadStream('./filename.pdf').
pipe(bucket.openUploadStream('filename', {
chunkSizeBytes: 1048576,
metadata: { field: 'filename', value: 'myValue' }
}))
Find
const cursor = bucket.find({});
cursor.forEach(doc => console.log(doc));
Delete
cursor.forEach(doc => bucket.delete(doc._id));

Uncaught TypeError: fs.readFile is not a function

Node.js, Webpack
In this project using webpack, where installed FS.
This code need to read file, but returns error "Uncaught TypeError: fs.readFile is not a function"
const bookForm = document.querySelector(".book-form");
const select = document.querySelector(".select"); const fs = require("fs");
export function abc() { bookForm.addEventListener("submit", e => {
console.log(select.options[select.selectedIndex].text);
e.preventDefault();
fs.readFile("file.txt", function(error, data) {
console.log("file read");
if (error) throw error;
console.log(data); });
}); }
You cannot import the fs module in the browser, because the browser environment does not have access to the user's file system. fs is only available in the Node.js context (on the server) but not on the client (browser).
If you want to send files from the browser to the server, you can use <input type="file"> and let the user manually select the files they have to send. If you want to send a server file's contents to the browser, you can use HTTP communication (AJAX) or you can render it's content in a server-side computed HTML template.
Within your config file you can set the way in which assests like your txt file is uploaded. Then you simply use require('file.txt') to load it - no need to use fs.

how to upload image to backblaze using hapijs

I am trying to upload image to backblaze-b2 using hapi.js. I am using a plugin called easy-backblaze but while using it I need to mention the path of the file. But While importing the file using Hapijs I am not able to understand how to get that path.
This is the Code I have written and here in b2.uploadFile I need to mention the path of the file on local Drive:
var B2 = require('easy-backblaze');
var b2 = new B2('accountId', 'applicationKey');
b2.uploadFile('C:/Users/Lovika/Desktop/addDriver.png', {
name: 'addDriver.png', // Optional, renames file
bucket: 'testBucket', // Optional, defaults to first bucket
}, function(err, res) {
console.log('Done!', err, res);
});
Do I need to upload the file to the server first and then to backblaze or Is there any way to upload the file directly to backblaze

Use Cordova's Filetransfer plugin with express/blob storage

I am using Typescript and Cordova 4.0.
I have the following sample code:
uploadImages(imageUris: Array<string>): any {
var fileTransfer = new FileTransfer();
for (var i = 0; i < imageUris.length; i++) {
fileTransfer.upload(imageUris[i], encodeURI('http://3187cf3.ngrok.com/test/photos'), (success) => {
alert('success');
}, (err) => {
alert('error');
});
}
}
This corresponds to an express route:
var router = express.Router(),
test = test.controller;
router
.post('/test/photos', bind(test.uploadPhotos, test));
Which corresponds to a controller method:
uploadPhotos(req: express.Request, res: express.Response) {
console.log(req);
}
I can't seem to figure out how to, inside of my controller, grab the "file" or image I'm posting to my server using Filetransfer. It's not on req.body or req.query, and when I look through the entire req I can't seem to locate the file. The app flow is working enough to actually make the POST request to test/photos, I just don't know how to or if I can access the file at that point.
How does Filetransfer work, and how can I access the data I need in my controller so that I can push it to Azure Blob Storage?
It looks like you have everything setup correctly to send the data through to your controller. The issue is that you need to put the file on the request since cordova's filetransfer plugin doesn't do that by default.
You can do that with a popular library multer.
npm install multer --save-dev To install multer and save it to your package.json file.
In your express config file, add something like the following:
var multer = require('multer');
app.use(multer({ dest: path.resolve(config.root, 'public/img/') }))
'public/img/' is the path you would like for your image to be saved.
Now your req will have files on it. To upload a single file, you would use req.files.file. You'll want to use this variable to send your file to azure's blob storage using something like blobSvc.createBlockBlobFromLocalFile(containerName, fileName, filePath)
Since you're using Azure for remote storage, chances are you will want to remove the local file that multer has saved. I'd recommend using fs or rimraf to remove the file stored in public/img/, or whatever you set the path to in your express config. If you are using fs, you'll want to use the .unlink command.

Resources