How to store downloaded file local url in mongodb - mongodb

i want to store the url path of downloaded file in mongodb so i can later use the path to open the file in my app.
i tried to store but the problem is whenever i download new file it upadate with the previous one .
this is the backend code
router.post('/download',function (req, res) {
console.log(req.body)
User.updateOne({_id:req.body.userid},{$set:{downloadurl:req.body.downloadurl
}}).then((user)=>{
console.log(user);
res.status(200).send({
data:user,
message:'success'
})
}).catch((err)=>{
console.log(err)
res.status(500).send({
data:err,
message:'not success'
})
})
});
this is the backend of ui
export async function DownloadUrl(data) {
let result = await fetch(url + 'user/download', {
method: 'POST',
body: JSON.stringify(data),
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
}
}).then(response => response.json());
console.log(result);
return result;
}

The problem here is that your urls are being stored in a plain text field. You need to store them in an array and, instead of using $set, that will overwrite the previous data, start using $push, that will append data to your url array:
router.post('/download',function (req, res) {
console.log(req.body)
User.updateOne(
{_id:req.body.userid},
{$push:{download_urls:req.body.downloadurl}}
).then((user)=>{
console.log(user);
res.status(200).send({
data:user,
message:'success'
})
}).catch((err)=>{
console.log(err)
res.status(500).send({
data:err,
message:'not success'
})
})
});
This way, you will end up with a User document like the one below:
{
"_id": "some_id_value",
// [...]
"dowload_urls": [
"someurl1",
"someurl2",
"someurl3"
]
}

Related

Content-type using axios

I'm working with React and axios. I'm trying to fetch the response using axios however, unable to understand why I'm getting wrong content-type even though I'm setting it in my backend code.
Code (backend):
router.get(url, async (req, res) => {
// return new Promise(async (resolve, reject) => {
try {
if (file exists) {
var fileContents = Buffer.from(document[0].data, "base64"); //document contains the data from the postgres database
var readStream = new stream.PassThrough();
readStream.end(fileContents);
res.set(
"Content-disposition",
"attachment; filename=" + document[0].fileName
);
res.setHeader("content-type", document[0].fileType);
readStream.pipe(res);
console.log("+++++++++++++++++++");
console.log(res);
console.log("+++++++++++++++++++");
return;
} else {
res.json({
status: 0,
message: "File not found",
});
return;
}
// resolve({ document });
} catch (err) {
console.log(err);
}
});
The above backend code works absolutely fine. I even printed the response to check whether the content-type is setting or not. I'm even providing the output snippet for that as well
However, in the frontend if I try to fetch the response this is what I'm receiving
I'm not sure what's wrong. Why I'm receiving wrong content-type. Even the content length is same for any sort of file which I try to download.
The axios call :
let response = await Axios.get(fileURL, {
responseType: "blob"/"arraybuffer",
Authorization: "Bearer " + token,
});
Response.data output :
Any help will be appreciated!

Put / Update to my MongoDb with Express, immutable error of cross _id field

So I am sending data of a mission, the startdate and the finish date. However I am not able to put any changes into the database as it believes I get an immutable error with mongoDB... I would like to stick with using the .then method for my js code.
My other methods are working properly, I just can't get this update method right...
app.put('/missions/:id', function (req, res) {
if (req.user) {
model.Mission.findById(req.params.id).then(function(Mission){
console.log("req.body.secret_mission: ",req.body.secret_mission)
Mission['secret_mission'] = req.body.secret_mission;
Mission['start'] = req.body.start;
Mission['complete'] = req.body.complete;
Mission.update().then(function(){
res.set('Access-Control-Allow-Origin', '*');
res.sendStatus(201);
});
});
}else{
res.sendStatus(401);
}
});
Error I receive in the command line
I was able to use all the help provided to come up with a working solution and keep consistent to how I am calling the rest of my code. A big thanks to those that responded!!
Rather than setting the elements in my collection beforehand I am supposed to do it in the update request. Instead of calling 2 methods I used the findOneAndUpdate.
app.put('/missions/:id', function (req, res) {
if (req.user) {
model.Mission.findOneAndUpdate(
{'_id' : req.params.id},
{ $set: {"secret_mission" : req.body.secret_mission,
"start" : req.body.start},
"complete" : req.body.complete
}).then(function(err, missions){
if (err) return res.json({Error: err});
res.json(missions);
});
} else {
res.sendSatus(401);
}
});
I've cleaned up Your code:
removed req.user check to middleware,
included cors module to not to play with CORS headers in every handler
used async/await stuff to give it more synchronous look
mission/:id route handler just have concrete logic without garbage
Check this solution:
const cors = require('cors'); // install: npm i --save cors
const _ = require('lodash'); // install: npm i --save lodash
app.use(cors());
const isUserAuthorized = (req, res, next) => {
if (!req.user) return res.status(401).send();
next();
}
app.put(
'/missions/:id',
isUserAuthorized,
async (req, res) => {
try {
const mission = await model.Mission.findById(req.params.id);
if (!mission) return res.status(404).send();
mission.set(_.pick(req.body, ['secret_mission', 'start', 'complete']);
await mission.save();
res.status(201).send();
}
catch (error) {
console.log(error);
res.status(500).send();
}
});
or if You don't care if record in db exist or not, so You can just push update directly:
app.put(
'/missions/:id',
isUserAuthorized,
async (req, res) => {
try {
const data = _.pick(req.body, ['secret_mission', 'start', 'complete']);
await model.Mission.update({_id: req.params.id}, {$set: data});
res.status(201).send();
}
catch (error) {
console.log(error);
res.status(500).send();
}
});

Upload image from data url to Axios?

Ive been uploading image files to an API (Graphcool) with this, and everything was working fine:
fileUpload(file) {
let data = new FormData();
data.append('data', file);
axios
.post(`https://api.graph.cool/file/v1/MY-PROJECTID`, data, {
headers: {
'Content-Type': 'multipart/form-data',
},
})
.then(res => {
console.log(res)
});
}
In the code above the file was passed from a <input type="file" />
However now I'm using React Avatar Editor to allow users to crop images and ensure they are a square:
https://github.com/mosch/react-avatar-editor
When you access the image from React Avatar Editor it comes in the form of a data url (via Canvas.toDataURL()).
How can I upload a data url with Axios? Do I need to first convert the image to an actual 'file' in the browsers memory?
This is a duplicate of below thread just in a different language
Sending canvas.toDataURL() as FormData
You need to change your code like below
function fileUpload(canvas) {
let data = new FormData();
canvas.toBlob(function (blob) {
data.append('data', blob);
axios
.post(`https://api.graph.cool/file/v1/MY-PROJECTID`, data, {
headers: {
'Content-Type': 'multipart/form-data',
},
})
.then(res => {
console.log(res)
});
});
}

How upload and save image using Sails and MongoDB

I'm working on a project and I'm using a backend sails js, a MongoDB as database and front-end React js.
I have a problem on the upload image.
Here is the code Sails backend and when I test it in PostMan, I got this result (result test PostMan), and the image is not stored in the specified folder but a value containing id and name of file is inserted in MongoDB,
uploadFile: function (req, res) {
var image= req.file('avatar');
image.upload({
adapter: require('skipper-gridfs'),
uri: 'mongodb://localhost:27017/name_db.name_collection',
dirname: '../../assets/images/'
}, function (err, filesUploaded) {
if (err){
return res.header("Access-Control-Allow-Origin", "*");
/*res.negotiate(err);*/res.json(err);
}
else{
return
res.header("Access-Control-Allow-Origin", "*"); res.ok({
files: filesUploaded,
textParams: req.params.all()
});
}
});
},
result test postMan
And here is the Reactjs front-end code
_handleSubmit(e) {
e.preventDefault();
// TODO: do something with -> this.state.file
fetch('http://localhost:1337/uploadPhoto/logos', {
method: 'POST',
body: JSON.stringify({avatar:this.state.file})
})
.then((response) => response.json())
.catch((err) => { console.log(err); });
}
Sails version 0.12,
React version 15.5,
and MongoDB version 3.4.9.
Thanks for your help
There is no dirname parameter for skipper-gridfs adapter because the file won't be stored onto the local file system.
Skipper will store the file into the MongoDB database.
U need to send it as form Data
let formData = new FormData()
console.log(values);
await formData.append('profile_picture',values.profile_picture.rawFile,values.profile_picture)
await fetch('http://localhost:1337/api/moderators',{
body:formData,
method:'POST',
credentials:'include' //If Using Session for react-app instead of JWT token
})

ng-file-upload accessing data sent in upload

I am sending my data like. I am new to angular. I am not able to access the userDetails in my post request.
Upload.upload({
url: '/api/upload/',
data: {'File': File, 'userDetails': userDetails}
});
Server Code:
userRouter.route('/upload')
.post(function(req, res) {
console.log(req.data);
upload(req, res, function(err) {
if(err) {
res.json({ error_code:1, err_desc:err });
return;
}
res.json({ error_code:0, err_desc:null });
})
});
the field req.data is undefined
I'm new on angularjs too and I had the same problem. I made use of https://github.com/expressjs/node-multiparty to get the data sent from ng-file-upload.
I hope it helps you too.