How upload and save image using Sails and MongoDB - 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
})

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!

How to store downloaded file local url in 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"
]
}

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.

Nativescript Autosync with server use REST API

Hello Nativescript user,
I have build nativescript App that get data from REST API and save to application-settings. Something like this :
fetch(config.apiUrl, {
method: 'GET',
headers: {
"X-Auth-Token": sTOKEN
}
}).then(function (response) {
return response.json();
}, function (e) {
console.log("Error occurred " + e);
})
.then(function (data) {
appSettings.remove(sPARAMETER_DATA);
appSettings.setString(sPARAMETER_DATA, JSON.stringify(data.sort()));
arrayData.set('DATA', new observableArray.ObservableArray(data.sort()));
});
So, if want data uptodate must GET again.
The question : Can use this appSettings save data locally like SQLite ? And how to autosync with server use REST API JSON ?
Thanks anyway

How send string/image base64 to Sailsjs - Skipper with ajax

Currently I am capturing the image of the camera, this Base64 format,and I'm sending through ajax.
xhr({
uri: 'http://localhost:1337/file/upload',
method: 'post',
body:'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAA...'
}
0 file(s) uploaded successfully!
Here is a nice link that will guide you to do send an image from an Ajax Client to an ajax server.
http://www.nickdesteffen.com/blog/file-uploading-over-ajax-using-html5
You can read this sails documentation to receive files on a sails server :
http://sailsjs.org/documentation/reference/request-req/req-file
You can do as the following example :
Client side ( ajax ):
var files = [];
$("input[type=file]").change(function(event) {
$.each(event.target.files, function(index, file) {
var reader = new FileReader();
reader.onload = function(event) {
object = {};
object.filename = file.name;
object.data = event.target.result;
files.push(object);
};
reader.readAsDataURL(file);
});
});
$("form").submit(function(form) {
$.each(files, function(index, file) {
$.ajax({url: "/ajax-upload",
type: 'POST',
data: {filename: file.filename, data: file.data}, // file.data is your base 64
success: function(data, status, xhr) {}
});
});
files = [];
form.preventDefault();
});
Server side ( sails ) :
[let's say you have a model Picture that take an ID and a URL]
[here is a sample of Picture controller, just to give you an idea]
module.exports = {
uploadPicture: function(req, res) {
req.file('picture').upload({
// don't allow the total upload size to exceed ~10MB
maxBytes: 10000000
},
function onDone(err, uploadedFiles) {
if (err) {
return res.negotiate(err);
}
// If no files were uploaded, respond with an error.
if (uploadedFiles.length === 0){
return res.badRequest('No file was uploaded');
}
// Save the "fd" and the url where the avatar for a user can be accessed
Picture
.update(777, { // give real ID
// Generate a unique URL where the avatar can be downloaded.
pictureURL: require('util').format('%s/user/pictures/%s', sails.getBaseUrl(), 777), // GIVE REAL ID
// Grab the first file and use it's `fd` (file descriptor)
pictureFD: uploadedFiles[0].fd
})
.exec(function (err){
if (err) return res.negotiate(err);
return res.ok();
});
});
}
};
Hope this will help in your research.
I also recommand you to use Postman to test your API first, then code your client.