Image is not uploaded to defined folder in node.js - html

I have a small HTML template and what I want is to upload image from one location to another. After selecting and clicking on the upload button, response gives me "Uploaded successfully" But the image is not in the destination folder. Please look into the below code.
HTML
<form id="frmUploader" enctype="multipart/form-data" action="book/api/Upload/" method="post">
<input type="file" name="imgUploader" multiple />
<input type="button" name="submit" id="btnSubmit" value="Upload" onclick="upload()"/>
</form>
index.js
function upload() {
axios.post(baseUrlLocal+'/book/api/Upload', {headers: headers})
.then(response => {
console.log(response.data.success)
if (response.data.success) {
console.log("hi: "+response)
// $.notify("New Book is Added to your Library", "success");
}
})
.catch(function (error) {
console.log(error)
// $.notify("Please check all the details","warn");
});
}`
book.js
var Storage = multer.diskStorage({
destination: function(req, file, callback) {
callback(null, "../public/images/");
},
filename: function(req, file, callback) {
callback(null, file.fieldname + "_" + Date.now() + "_" +
file.originalname);
}
});
var upload = multer({
storage: Storage
}).array("imgUploader", 3);
router.get("/image", function(req, res) {
res.sendFile(__dirname + "/index.html");
});
`router.post("/api/Upload", function(req, res) {
upload(req, res, function(err) {
if (err) {
return res.end("Something went wrong!");
}
return res.end("File uploaded sucessfully!.");
});
});`

Related

Cannot POST /api/dogs

I create one basic project in nodejs but when I submit the data it says cannot post api/dogs. https://vfs.cloud9.us-east-2.amazonaws.com/vfs/3199fe30e54d4e63aa04c42b20416f0e/preview/index.html for live test
Here is my index.html
<h1>Dogs</h1>
<h2>Add a Dog</h2>
<form action="/api/dogs" method="POST">
<label for="name">Enter Dog Name: </label>
<input type="text" id="name" name="name" autofocus />
<br/>
<label for="description">Enter Dog Description </label>
<textarea type="description" id="description" name="description" >
</textarea>
<input type="submit" value="Submit" />
Create a new folder called data, and create a file inside this folder called connection.js. This file will export a database connection pool.
exports.connectionPool = mysql.createPool({
connectionLimit:10,
host : 'localhost',
user : 'root',
password : 'root',
database : 'a1',
multipleStatements: true
});
create another file in data called setup.js. We'll use this file to setup the required tables in our database. In fact, our database will contain only one table.
const {
connectionPool
} = require('./connection.js'); // requires a file in current directory
connectionPool.query('DROP TABLE IF EXISTS dogs;', (error, results) => {
if (error) {
console.log(error.message);
process.exit();
} else {
console.log("Success: dog table dropped!");
}
});
var createSql = "CREATE TABLE dogs (dog_id INT(11) NOT NULL AUTO_INCREMENT, name VARCHAR(255) NOT NULL, description TEXT NOT NULL, PRIMARY KEY (dog_id) );";
connectionPool.query(createSql, (error, results) => {
if (error) {
console.log(error.message);
process.exit();
} else {
console.log("Success: dog table Created!");
}
});
And Here is index.js code
const {
connectionPool
} = require('./data/connection.js');
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
// Create application/x-www-form-urlencoded parser
var urlencodedParser = bodyParser.urlencoded({
extended: true
})
app.use(express.static('public'));
app.get('/', function (req, res) {
res.sendFile(__dirname + "/" + "index.html");
})
app.post('/api/dogs', urlencodedParser, function (req, res) {
// Prepare output in JSON format
connectionPool.query("INSERT INTO dogs (name, description) VALUES ('" + req.body.name + "', '" + req.body.description + "');", (error, results) => {
if (error) {
console.log(error.message);
process.exit();
} else {
console.log("Success: dog inserted");
}
});
res.end(JSON.stringify(req.body));
})
app.get('/api/dogs', function (req, res) {
connectionPool.query("SELECT * FROM dogs LIMIT " + req.query.offset + ", " + req.query.count, (error, results) => {
if (error) {
console.log(error.message);
process.exit();
} else {
if (results === undefined || results.length == 0) {
res.status(404).send("nothing found");
} else {
console.log(results);
res.end(JSON.stringify(results));
}
}
});
})
app.get('/api/dogs/id', function (req, res) {
connectionPool.query("SELECT * FROM dogs where dog_id='" + req.query.id + "'", (error, results) => {
if (error) {
console.log(error.message);
process.exit();
} else {
console.log(results);
res.end(JSON.stringify(results));
}
});
})
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log("Example app listening at http://%s:%s", host, port)
})
[1]: https://vfs.cloud9.us-east-2.amazonaws.com/vfs/3199fe30e54d4e63aa04c42b20416f0e/preview/index.html
Your form action is incomplete you have to call the absolute url for hitting your backbends follows
<form action="http://localhost:8081/api/dogs" method="POST">

req.file() isn't able to fetch multiple files

My html code is
<form action="/file_upload" method="POST" enctype="multipart/form-data">
<input type="file" name="photos" id="photos" accept='image/*' multiple>
<input type="submit" value="Upload" id="upload_my_photos" disabled>
</form>
In sails I am using
uploadFiles = req.file("photos");
This is only fetching just single file.
Edit : I would also like to save the individual files. Below is the code I am using but no files are getting uploaded:
req.file('photos').upload(function (err, uploadedPhotos) {
if (err) return res.serverError(err);
async.eachSeries(uploadedPhotos,
function (uploadedFile, callback) {
sails.log("upload file size and name is " + uploadedFile.size + " " + uploadedFile.filename);
req.file(uploadedFile).upload({
dirname: "path/to/directory",
// saveAs: function (file, cb) { cb(null, file.filename); }
},
function onUploadComplete(err, files) {
if (err) return res.serverError(err);
if (files.length === 0) {
return res.badRequest('No file was uploaded');
}
sails.log("files uploaded");
});
}, function (err) {
// if any of the saves produced an error, err would equal that error
if (err) {
console.log(err);
} else {
return res.status(200).send({ success: false, message: "failed to upload" });
}
});
});
Sails req.file() is representing an incoming multipart file upload from the specified field.
You need to subscribe to the request with a callback in which the uploaded files will be passed as an second argument:
req.file('photos').upload(function (err, uploadedPhotos){
if (err) return res.serverError(err);
return res.json({
message: uploadedPhotos.length + ' file(s) uploaded successfully!',
files: uploadedPhotos
});
});

Angular NodeJs multer upload img req.file is always undefined

I'm getting req.file as undefined. I have tried everything. I have searched for other solutions, but it's not a problem in input name="avatar" attr and upload.single("avatar").
Also, I'm getting an error in the console:
Error for image upload 400 - Bad Request
{"code":"ER_PARSE_ERROR","errno":1064,"sqlMessage":"You have an error
in your SQL syntax; check the manual that corresponds to your MySQL
server version for the right syntax to use near '?)' at line
1","sqlState":"42000","index":0,"sql":"INSERT INTO avatars (image)
VALUES(?)"}
I would say that it is because req.file is undefined.
Please, help me to understand what I'm doing wrong.
api.js:
var storage = multer.diskStorage({
destination: function(req, file, callback) {
callback(null, "./assets/images/uploads");
},
filename: function(req, file, callback) {
callback(null, file.fieldname + "_" + Date.now() + "_" +
file.originalname);
}
});
var upload = multer({
storage: storage,
limits: {fileSize: 1000000},
fileFilter: function(req, file, cb) {
checkFileType(file, cb);
}
});
function checkFileType(file, cb) {
const filetypes = /jpeg|jpg|png|gif/;
const extname = filetypes.test(file.originalname.toLowerCase());
const mimetype = filetypes.test(file.mimetype);
if(extname && mimetype) {
return cb(null, true);
} else {
cb('Error: Images only');
}
}
router.post("/upload", upload.single('avatar'), function(req, res) {
console.log(req.file); // <- ALWAYS UNDEFINED
pool.getConnection(function(err, connection) {
if (err) throw err;
connection.query('INSERT INTO avatars (image) VALUES(?)', req.file,
function (error, results, fields) {
if(error){
console.log("Error: " + error);
res.status(400).send(error);
}
res.status(200).end(JSON.stringify(results));
connection.release();
if (error) throw error;
});
});
});
html:
<form enctype="multipart/form-data">
<input class="form-control"
(change)="onFileSelected($event)"
type="file" name="avatar">
<button type="submit" class="btn btn-danger float-right" (click)="onUpload()">Upload image</button>
</form>
ctrl:
onFileSelected(event) {
if(event.target.files.length > 0) {
this.uploadImage = <File>event.target.files[0];
}
}
onUpload() {
if(this.uploadImage) {
this.friendService.uploadFile(this.uploadImage)
.subscribe(
data => {
return true;
},
error => {
console.error('Error for image upload ' + error);
return false;
})
}
}
service:
uploadFile(file): Observable<any> {
return this.http.post(`${this.apiUrl}/upload`, file)
.map(res => res.json())
.catch(this.handleError);
}
db mysql avatars table:
Field - image
Type - blob
Null - NO
Key Default Extra - Empty
while uploading file it should be form data and content type should be multipart/form-data
For your reference: File Upload In Angular?.
I hope this will help you.

Show success message of upload action HTML, NodeJS

I upload a file in HTML with nodejs module MULTER:
<form enctype = "multipart/form-data"
action = "/upload"
method = "POST">
<input type="file" name="file" >
<p></p>
<input type="submit" value="Upload File" name="submit" class="btn btn-primary">
</form>
<span>{{submit.message}}</span>
I want to show the response message not in on a new page which is now, I want to show it in the message span.
var upload = multer({ storage : storage}).single('file');
router.post('/upload', function(req, res){
upload(req, res, function(err) {
if(err){
return res.status(400).send({
message: 'wrong'
});
console.log("Error: '" + err + "'");
}else{
return res.status(200).send({
message: 'fine'
});
console.log('Uploaded file: ' + req.file.filename);
}
});
});
angularjs:
this.submit = function() {
$http.post("/upload", data)
.then(
function(res) {
console.log("posted successfully");
this.message = "succesful";
},
function(res) {
console.log(res.data.message);
this.message = res.data.message
}
);
}
How can I parse the response message to the html file without opening a new page. I want to show the response message in the html span response.
Does anyone know how to do this?

separate file uploads node.js

I want to know the easiest way to handle two separate file uploads, one for images and the other for audio. right now I am using multer and it uploads all multipart uploads to the same location. can I specify different locations for both file uploads?
Assuming you want to save the files to disk, you can do something like this:
var storage = multer.diskStorage({
destination: function(req, file, cb) {
if (file.fieldname === 'image-file') {
return cb(null, 'folder-for-image-uploads');
}
if (file.fieldname === 'audio-file') {
return cb(null, 'folder-for-audio-uploads');
}
cb(new Error('Unknown fieldname: ' + file.fieldname));
},
filename: function(req, file, cb) {
if (file.fieldname === 'image-file') {
return cb(null, 'image-filename.jpg');
}
if (file.fieldname === 'audio-file') {
return cb(null, 'audio-filename.mp3');
}
cb(new Error('Unknown fieldname: ' + file.fieldname));
}
});
var upload = multer({storage: storage});
app.post('/endpoint', upload.fields([{name: 'image-file', maxCount: 1}, {name: 'audio-file', maxCount: 1}]), function(req, res) {
// handle request, files already saved to disk
res.sendStatus(200);
}
For this to work, you need the name of input HTML elements to match the fieldname property, e.g.:
<form method="POST" action="/endpoint" enctype="multipart/form-data">
<input type="file" name="image-file">
<input type="file" name="audio-file">
<input type="submit">Submit</input>
</form>