How to handle file upload using sequelize + mysql + express js? - mysql

I'm developing a simple software college project that needs pdf/doc file upload. But here comes the bottleneck: I couldn't find anywhere an example and example of this feature using the Sequelize ORM.
Has anyone done something similar using this framework?
*By the way, I know there are several npm packages for express(), but I must use sequelize.
Any advice is welcome.
Thanks in advance ;)

Configure your express app with multer. Read over the documentation for multer, but in short you store the path of the uploaded file:
const multer = require('multer')
const express = require('express')
const Sequelize = require('sequelize')
const sequelize = new Sequelize('database', 'username', 'password')
const MyModel = sequelize.define('myModel', {
filePath: Sequelize.STRING,
})
const express = express()
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, './app/uploads')
},
filename: (req, file, cb) => {
cb(null, file.originalname)
}
})
app.post('/upload', multer({ storage }).single('example'), async (req, res) => {
// This needs to be done elsewhere. For this example we do it here.
await sequelize.sync()
const filePath = `${req.file.destination}/${req.file.filename}`
const myModel = await MyModel.create({ filePath })
})

A slightly simpler example (from) using AJAX.
Add to your node.js
var multer = require('multer');
const storage = multer.diskStorage({
destination: (req, file, callback) => {
console.log(req);
callback(null, './uploads');
},
filename: (req, file, callback) => {
console.log(req);
callback(null, Date.now() + file.originalname);
}
});
var upload = multer({storage:storage}).single('myFile');
app.post('/dashboard/myFile', function(req,res){
upload(req,res,function(err){
//console.log("owen",req.file,err);
if (err)
return res.end("error uploading file");
res.end("file is uploaded");
});
});
And in your HTML
<form id="myForm" name="myForm" enctype="multipart/form-data" method="post">
<input id="myFile" name="myFile" type="file">
<button type="submit" class="btn btn-primary">Submit</button>
</form>
<script>
var form = document.forms.namedItem("myForm");
form.addEventListener('submit', function(ev){
var myFile = document.getElementById('myFile').files[0];
var oData = new FormData(form);
var oReq = new XMLHttpRequest();
oReq.open("POST","/uploadFile",true);
oReq.onload = function(oEvent){
if(oReq.status == 200) {
console.log("success",oEvent);
} else {
console.log("fail",oEvent);
}
}
oReq.send(oData);
ev.preventDefault();
},false);
</script>

Related

error column cannot be null, trying to upload file into sql

i am still new in node js, and i am trying to make some backend with file upload/ image upload function that can be stored in sql, i am trying using multer but it cant read my file while testing in postman body. anybody can help me where i do wrong?
here is my controller
const { db } = require('./db');
const bodyParser = require('body-parser');
const getgambar = (req, res) => {
const sqlQuery = "SELECT * FROM gambar";
db.query(sqlQuery, (err, result) => {
if (err) {
console.log(err);
} else {
res.send(result);
console.log(result);
}
});
};
const addgambar = (req,res) => {
const idimg = req.body.idimg;
const gambar = req.file.gambar;
console.log()
const sqlQuery = "INSERT INTO image (idimg,gambar) VALUE (?,?)";
db.query(sqlQuery, [idimg,gambar], (err, result) => {
if (err) {
res.send({
message: "error",
err
})
} else {
res.send({
message: "YES"
})
}
});
};
module.exports = {
getgambar,
addgambar,
};
here is my route
const express = require('express');
const router = express.Router();
const multer = require('multer');
const path = require('path');
const ctrl = require('./gambarctrl');
const storange = multer.diskStorage({
destination: './uploads',
filename: (req, file, cb) => {
return cb(null, `${file.fieldname}_${Date.now()}${path.extname(file.originalname)}`)
}
})
const upload = multer({
storange: storange
})
router.get('/image/display', ctrl.getgambar)
router.post('/image',upload.single('gambar'), ctrl.addgambar)
module.exports = router;
and here my index
const { db } = require('./db');
const express = require('express');
const bodyParser = require('body-parser')
const cors = require('cors');
const app = express();
const fileUpload = require('express-fileupload');
const gambarroute = require ('./gambarroute');
const multer = require('multer');
app.use(cors());
app.use(express.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(gambarroute);
app.listen(3000, () => {
console.log('on port 3000!');
});
i am still quite new in node js and i am still searching for tutorial, i appriciate for the help.
Two problems here...
Multer puts the single uploaded file into req.file so you should use
const gambar = req.file; // no `.gambar`
Assuming your DB column is a BLOB or BINARY type, you need to provide a Buffer.
Since you're storing the images within the DB, you don't need to use DiskStorage. Use MemoryStorage instead which provides a Buffer out-of-the-box
const upload = multer({
storage: multer.memoryStorage(), // watch your spelling
})
Then bind the .buffer property in your query.
db.query(sqlQuery, [idimg, gambar.buffer], (err, result) => {
// ...
});
To respond with the image from Express, use something like this
router.get("/image/display/:id", (req, res, next) => {
db.query(
"SELECT `gambar` FROM `image` WHERE `idimg` = ?",
[req.params.id],
(err, results) => {
if (err) {
return next(err);
}
if (!results.length) {
return res.sendStatus(404);
}
// set the appropriate content type
res.set("Content-Type", "image/jpg");
res.send(results[0].gambar);
}
);
});
and from the frontend...
<img src="http://localhost:3000/image/display/some-id" />

Using multer with nodejs

I am trying to upload a file from my page to node server.
I can see form data are arriving in the router on server.
But no file is saved in upload folder.
What am I doing wrong?
//router unit
const express = require('express');
const router = express.Router();
const multer = require('multer');
const storage = multer.diskStorage({
destination: (req, file, cb) => {
console.log('chegei')
cb(null, "uploads/")
},
filename: (req, file, cb) => {
console.log('chegei2')
cb(null, Date.now() + "-" + file.ogirinalname)
},
});
module.exports = function (page) {
router.post('/SendMsgBase64', async (req, res) => {
var upload = multer({ storage: storage }).single('userFile');
upload(req, res, function (err) {
if (err) {
console.log(err);
return res.send({ "data": "Error uploading file." });
}
return res.send({ "data": "File is uploaded" });
});
return router
}
//app.js unit
const express = require('express')
const app = express()
const server = require('http').Server(app)
const io = require('socket.io')(server)
const WARoutes = require('../routes/WARoutes');
const path = require('path');
const bodyParser = require('body-parser');
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res) => {
res.sendFile('/index.html');
})
app.use('/whats', WARoutes(this.page));
//html
<form id="uploadForm">
<input type="file" name="userFile" />
<input type="button" value="Upload Image" onclick="uploadFile();">
<span id="status"></span>
</form>
<script>
uploadFile = () => {
var formData = new FormData();
debugger
var logoImg = $('input[name="userFile"]').get(0).files[0];
formData.append('logo', logoImg);
var objArr = [];
objArr.push({ "id": "123", "name": "luiz" });
//JSON obj
formData.append('objArr', JSON.stringify(objArr));
$.ajax({
url: "/whats/SendMsgBase64",
type: "POST",
processData: false,
contentType: "application/x-www-form-urlencoded",
data: formData,
complete: function (data) {
alert("success");
}
})
};
</script>
According to multer's github page, if you have not created the uploads directory, it may go something wrong.
If this is the case, creating the directory on your own or passing a string value to destination property is the solution for you.
https://github.com/expressjs/multer
Note: You are responsible for creating the directory when providing destination as a function. When passing a string, multer will make sure that the directory is created for you.

Creating a QR-code containing a link in NodejS

I'm working on a project right now, i need to create a qrcode that contains a specific information in NodeJS. I have started by creating the canvas in HTML, and take it in NodeJS
<canvas id="canvas" width="300" height="300"></canvas>
And then in my NodeJS file, i'm launching my function
const fs = require('fs');
const qrcode = require('qrcode');
module.exports = {
generateQr: function(link){
var canvas = new qrcode(document.getElementById('canvas'));
qrcode.toCanvas(canvas, link, function (error) {
if (error) console.error(error)
console.log('success!');
});
}
};
Unfortunately, i got the error :
ReferenceError: document is not defined
From the above code, does it look correct ? Does the Qrcode get the data i'm passing, and then what should i do so the QR-code appear in my HTML ?
Thank you for your help
document is a browser-specific global object, you can't access it in node
In node environment, you could generate an image with QR code and use it.
Example:
Async/Await style:
const fs = require('fs');
const qrcode = require('qrcode');
module.exports = {
generateQr: async link => {
const qrCodeDataUrl = await qrcode.toDataURL(link);
// ...
}
};
Promise style:
const fs = require('fs');
const qrcode = require('qrcode');
module.exports = {
generateQr: link => {
qrcode.toDataURL(link)
.then(data => {
const qrCodeDataUrl = data;
// ...
})
.catch(err => {
console.error(error);
// ...
});
}
};
Callback style:
const fs = require('fs');
const qrcode = require('qrcode');
module.exports = {
generateQr: link => {
qrcode.toDataURL(link, function(err, data) {
if (error) console.error(error);
const qrCodeDataUrl = data;
// ...
});
}
};
To render it in an HTML-file you could use template-engine of your choice:
Example with ejs:
const ejs = require('ejs');
// In some route
const qrCodeDataUrl = await generateQr('some link');
const html = ejs.render('<img src="<%= qrCodeDataUrl %>" />', {qrCodeDataUrl});
res.header('Content-Type', 'text/html');
res.send(html);
// ...
Note: It's a simplified example. Please check ejs docs for more details

File upload using mysql in express js

Currently i'm doing some projects using Express 4.x and in the project seems that want to handle file upload (example: upload image on form). I am using localhost as server (mysql), searching for clue most of people using multer but i can not get. any helps, i appreciate
Formidable which helps you parse and get files from the POST request
Example code:
const formidable = require('formidable');
const fs = require('fs');
const path = require('path');
// POST | /upload
app.post('/upload', (req, res) => {
const form = new formidable.IncomingForm();
form.parse(req, (error, fields, files) => {
if(error){
res.status(500);
console.log(error);
res.json({
error,
});
return false;
}
const image = files.image;
console.log(image.name) // pony.png
console.log(image.type) // image/png
// Get the tmp file path
const tmpFilePath = image.path; // /tmp/<randomstring>
// Rename and relocate the file
fs.rename(tmpFilePath, path.join(`${__dirname}/uploads/${image.name}`), error => {
if(error){
res.status(500);
console.log(error);
res.json({
error,
});
return false;
}
res.status(201);
res.json({
success: true,
upload_date: new Date(),
});
// Do all kinds of MySQL stuff lol
});
});
});

How to upload blob object of type video/webm from nodejs to Mongo DB?

I have to upload video blob object to Mongo DB using NodeJS.
For video i am using video.js https://github.com/collab-project/videojs-record
I am sending blob object to NodeJS using Ajax call like below.
var file={
name:'abc',
data: player.recordedData.video
};
$.ajax({
type: 'POST',
url: '/uploadVideo',
data: file,
dataType: 'JSON'
}).done(function(data) {
alert("success");
});
Here file is JSON object i wanted to save in my collection containing other fields like file name,blob data etc. At Node.js end I have below code
router.post('/uploadVideo',function (req, res ,next) {
var file=req.body;
console.log("file"+file);
var collection = db.get('test');
collection.insert(file, function(err, result){
console.log('video saved in mongo db');
res.send(file);
});
});
Console statement in which file object is printed works fine.
But getting 500 error while inserting the JSON in mongo DB collection.
Can anyone provide me a solution for inserting blob in collection? Also let me know if my code has any bug.
Thanks
I am not sure what middleware are you using? Here is the working sample which uses multer and body-parser.
Important piece of code:-
The form data field name (uploadfile) should match. And then read the file from the downloaded location using fs and set it in the document that will be inserted into MongoDB collection.
upload.single('uploadfile');
insertdata["file"] = fs.readFileSync(req.file.path);
Form data field name:-
File upload: <input type="file" name="uploadfile"><br>
Full HTML form:-
<form action="http://localhost:3000/filesave" enctype="multipart/form-data" method="post">
Username: <input type="text" name="username"><br>
File upload: <input type="file" name="uploadfile"><br>
<input type="submit" value="Send">
</form>
Working code:-
var express = require('express');
var Db = require('mongodb').Db,
Server = require('mongodb').Server,
bodyParser = require('body-parser')
fs = require('fs');
var db = new Db('test', new Server('localhost', 27017));
var multer = require('multer');
var upload = multer({ dest: 'uploads/' });
var collection, dbObj;
module.exports = {
};
var app = express();
app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
var exports = module.exports;
app.post("/filesave", upload.single('uploadfile'), function (req, res) {
db.open(function (err, success) {
if (err) {
console.log("DB connection error");
} else {
console.log("DB connection is successful");
console.log(req.body.username);
console.log(req.file);
var insertdata ={};
insertdata["username"] = req.body.username;
insertdata["file"] = fs.readFileSync(req.file.path);
db.collection("filesave").insert(insertdata, function (inserr, result) {
if (inserr) {
console.log(inserr);
db.close(true);
res.json(inserr);
} else {
db.close(true);
res.json("Successfully persisted in database");
}
});
}
})
});
app.listen(3000);
Data saved in MongoDB collection:-