NodeJS Multiparty file upload to Azure and a text field - node.js

I need to verify that a mongodb document exists before continuing with Azure file upload.
The form consists of a file and a text field, the logic that is needed is the following:
Form submission
Get the text field
Search in mongodb for a document with the text field data
If the item exist continue with file upload to Azure else return
File upload to Azure
Save the URL to the file in the same MongoDB document that was found in
The problem I'm facing is that I can't touch field data in form.on('part') and can't get it to work with using form.parse first.
This is my code, I'm willing to change libraries and do whatever it takes to get it working.
var form = new multiparty.Form();
var formField = "";
form.parse(req, function(err, fields, files) {
formField = fields.fieldinform[0];
});
console.log(formField); //empty async?
model
.findOne({ name: formField })
.then(obj => {
form.on("part", function(part) {
if (!part.filename) return;
var size = part.byteCount;
var name = part.filename;
var container = "test";
blobService.createBlockBlobFromStream(
container,
name,
part,
size,
function(error) {
if (error) {
console.log("failed");
}
}
);
});
})
.catch(e => {
//do not continue
});
Help would be highly appreciated!

After a lot of searching and not coming up with a proper answer I decided to go with jquery that changed the action URL of the form to /upload/textintextfield before submission and then grab that with req.params.textfield in node.
<script>
$('#fileUploadForm').submit(function() {
$('#fileUploadForm').attr('action', '/upload/addvideo/' + $('#textfield').val())
return true;
});
</script>

Related

How to change pug after first sending it in NodeJS

Somehow, I can't seem to change anything after first sending my pug file. I have an array of image URLs and am sending it to pug and receiving it in pug like this:
function putnewvalsinpug() {
db.get('URL', function (err, value) {
if (err) return console.log('', err);
var newnewval = ""
data = value;
data = data.toString()
var stringArray = data.split(" ");
console.log(stringArray);
app.get('/', (req, res) => {
res.render('index', {imgsrcs: stringArray});
});
})
}
each image in imgsrcs
a(href=image)
img(src=image)
when I add a URL to the database, I want my website to show the additional images after a refresh, but it only shows the new images after a server restart. I have tried running putnewvalsinpug() after adding an URL to the database and not only on startup, but that did not work.

Mongodb display searched document data in ejs file

I am trying to make it so that if I search for a name that Mongodb would search for that document and then that it would display it in the ejs file. And it should do that by changing the text field of a H4 field in the js file at the client side. But when I try to do this it would keep saying that "Query" (which is the name of the searched data that comes back from the document) is not defined. However I only try to give the h4 that name after mongodb has done the search and has brought back that data from the query. For this I am using: Mongodb, express, EJS and nodejs.
Index.js:
router.post('/searchplayer', ensureAuthenticated, function(req, res){
const {text} = req.body;
var input = text
User.findOne({charactername: text})
.then(user => {
if(user) {
const { MongoClient } = require("mongodb");
const url = 'mongodb+srv://test:test1234#databasetest.5f9jh.mongodb.net/Databasetest?retryWrites=true&w=majority';
console.log('player found')
MongoClient.connect(url, function(error, db) {
if (error) throw error;
var dbo = db.db("Databasetest");
var query = { charactername: text };
dbo.collection("users").find(query).toArray(function(error, query, result) {
res.render('main', {
user: req.user,
query,
})
if (error) throw error;
console.log(result);
db.close();
})
});
} else {
console.log("Player does not exist")
}
})
})
Some clarification:
1: The const text is the value that people type in the ejs file.
2: Then it starts to make a search in mongodb to see if that name comes up in any of the avaible documents and returns back that certain document like this: [{charactername: "Jordan"}] which I can see back in the console log.
But now I am trying to view this data in ejs by using this script in the main.ejs:
//Search for user
document.getElementById('playersearchbtn').addEventListener('click',showotheruserpopup)
//Show other user if one is found
function showotheruserpopup() {
if (document.getElementById('searchplayerinput').value.length > 0) {
localStorage.setItem("otherusermenu","open")
document.getElementById('otheruserpopup').style.visibility = "Visible"
var userField = document.getElementById('otherusername')
userField.textContent = "<%= query%>"
localStorage.setItem('userField', userField.textContent)
var retrieveduserField = localStorage.getItem('userField')
userField.textContent = retrieveduserField
} else {
alert('You have to search something..')
}
}
//Close other user popup
document.getElementById('otheruserbtn').addEventListener('click',closeotheruserpopup)
function closeotheruserpopup() {
document.getElementById('otheruserpopup').style.visibility = "Hidden"
}
The situation is that first off the otherusername textcontent element is empty at the start but once it has done this search in mongodb the field text should change to the query which is the data that I got back from the mongodb search. But when I try this EJS will keep telling me that query is not defined in the script at the userField.textContent. Which I found weird because even trough this should get only triggerd by the script, but EJS will just automaticly say that it is not defined. But then I would not know how I could define because it only will exist once the actual search has been made.
How could I fix this issue?
I have found a work around for my problem, I made it render another page where it will shows the data after mongodb has searched for it. This seems to work fine.

Amazon S3 - Edit uploaded Images

OVERVIEW: I'm using Amazon S3 to let users upload images. I've been working on an edit route so that users can edit their images after they've uploaded them. I'm doing this via a PUT route. This is my current solution. It works as far as overriding the current images.
PROBLEM: If a user selects zero new images it overwrites the old images with blank filepaths. Aka no images show up after editing. The same thing happens if a user only tries to edit one image, that one image will update but the others are overwritten with blank filepaths so no images show.
QUESTION: What is the correct way to let a user edit an image using Amazon S3 and Multer-S3?
Thanks for any help! :)
app.put("/:id", function(req, res){
upload(req,res,function(err) {
if(err) {
console.log(err);
res.redirect('/')
}
var filepath = undefined;
var filepath2 = undefined;
var filepath3 = undefined;
if(req.files[0]) {
filepath = req.files[0].key;
}
if(req.files[1]) {
filepath2 = req.files[1].key;
}
if(req.files[2]) {
filepath3 = req.files[2].key;
}
var image = filepath;
var image2 = filepath2;
var image3 = filepath3;
var newData = {image: image, image2: image2, image3: image3}
Rental.findByIdAndUpdate(req.params.id, {$set: newData},
function(err, rentals){
if(err){
req.flash("error", err.message);
res.redirect("back");
} else {
req.flash("success","Successfully Updated!");
res.redirect("/rentals/" + rental._id);
}
});
});
});
});
You should validate the user input before calling the downstream updates.
You should not need to call Rental.findByIdAndUpdate if the values have not been populated correctly (as there is nothing to update).
I can't offer more help without seeing the code for Rental.

How to retrieve image file from Mongo using Sails.JS + GridFS?

I'm currently building web using Sails.js and got stuck in retrieving image file from GridFS. I have successfully uploading the file using skipper-gridfs to my mongo gridfs. I have no idea to display the file in the correct way (I'm new in Sails.js and Node system)
Here is my code for retrieving image file from gridfs looks like in FileController.js (I'm using gridfs-stream):
show: function (req, res, next) {
var mongo = require('mongodb');
var Grid = require('gridfs-stream');
var buffer="";
// create or use an existing mongodb-native db instance
var db = new mongo.Db('testDb', new mongo.Server("192.168.0.2", 27017), {safe:true});
var gfs = Grid(db, mongo);
// streaming from gridfs
var readstream = gfs.createReadStream({
filename: 'e1ecfb02-e095-4e2f.png'
});
//check if file exist
gfs.exist({
filename: 'e1ecfb02-e095-4e2f.png'
}, function (err, found) {
if (err) return handleError(err);
found ? console.log('File exists') : console.log('File does not exist');
});
//buffer data
readstream.on("data", function (chunk) {
buffer += chunk;
console.log("adsf", chunk);
});
// dump contents to console when complete
readstream.on("end", function () {
console.log("contents of file:\n\n", buffer);
});
}
When I ran it, the console showed nothing.
There is no error either.
How should I fix this?
Additional Question:
Is it better & easier to store/read file to/from local disk instead of using gridfs?
Am I correct in choosing gridfs-stream to retrieve the file form gridfs?
In the skipper-gridfs codes and there's a 'read' method that accept fd value and returns the required file corresponding to that value. So, you just have to pull that file from mongo by that method and send as a response. It should work file.
download: function (req, res) {
var blobAdapter = require('skipper-gridfs')({
uri: 'mongodb://localhost:27017/mydbname.images'
});
var fd = req.param('fd'); // value of fd comes here from get request
blobAdapter.read(fd, function(error , file) {
if(error) {
res.json(error);
} else {
res.contentType('image/png');
res.send(new Buffer(file));
}
});
}
I hope it helps :)
Additional Questions:
Yes, using gridfs is better both in performance and efficiency. And normally mongodb has a limitation of 16MB probably for binary files, but using gridfs you can store any size file, it breaks them in chunks and stores them.
Retrieving has been shown above.
You can now use skipper-gridfs in sails to manage uploads/downloads.
var blobAdapter = require('skipper-gridfs')({uri: 'mongodb://jimmy#j1mtr0n1xx#mongo.jimmy.com:27017/coolapp.avatar_uploads' });
Upload:
req.file('avatar')
.upload(blobAdapter().receive(), function whenDone(err, uploadedFiles) {
if (err) return res.negotiate(err);
else return res.ok({
files: uploadedFiles,
textParams: req.params.all()
});
});
Download
blobAdapter.read(filename, callback);
Bear in mind the file name will change once you upload it to mongo, you have to use the file name returned in the first response.

NodeJS MongoDB : Multiple save requests not working

I am using node-mongodb-native in my application. I send multiple POST requests to nodejs server to save/update each documents, but only one document is getting updated and all other document are not changing. The data received in the server is correct.
save : function(req,res) {
data = req.body;
if(!data._id){
data._id = new ObjectID();
}else{
data._id = ObjectID(data._id);
}
mColl(req.params.collname, function (collection,db) {
collection.save(data, {safe:true}, function(err, result) {
if(err){
res.send(err);
}
else {
res.send(result);
}
});
});
}
I am not getting the response for the request also.
For starters, don't do this:
data = req.body;
When a new request comes in, you're overwriting the (global!) data variable, and all kinds of undefined stuff can happen. So always declare a new variable:
var data = req.body;

Resources