Uploading an image, frontend and backend - javascript

const { timeStamp, time } = require('console');
const express = require('express');
const fileUpload = require('express-fileupload');
const path = require("path");
const util = require('util');
const app = express();
const port = 3000;
app.use(express.json());
app.use(express.static('public'))
app.use('/css', express.static(__dirname + 'public/css'))
app.use('/images', express.static(__dirname + 'public/images'))
app.use('/js', express.static(__dirname + 'public/js'))
app.use(express.urlencoded({ extended: true }));
app.use(fileUpload());
app.use(express.static("./public"));
app.post("/upload", async (req, res) => {
try {
// File name, size and type values
const file = req.files.file;
const fileName = file.name;
const size = file.data.length;
const extension = path.extname(fileName);
const name = file;
// Allowed filetypes
const allowedExtensions = /png|jpg|dds|ico|mov|mp4|flv|avchd|avi|webm|mp3|aac|wav|flac|svg|webp|gif|bmp|tiff|psd|psb|blend|fbx|obj|raw|aep|prel|prproj|ai/;
// Mazimun file Size
if (!allowedExtensions.test(extension)) throw "Filetype not allowed"
if (size > 200000000) throw "File must be less than 200MB"
// Uploaded file name
const md5 = file.md5;
const URL = "/uploads/" + fileName + Date.now() + extension;
await util.promisify(file.mv)("./public" + URL);
// Errors and Success messages
res.json ({
message: "File uploaded successfully!",
url: URL,
})
} catch(err){
console.log(err);
res.status(500).json({
message: err,
})
}
})
app.listen(port, () => console.info(`Listening on port ${port}`))
So I have this script for uploading images to a folder in my public folder in the root directory of my website, I'm a real noob when it comes to js so, I was wondering how do I implement a button that let's the user select a file as well as a submit button and maybe perhaps a couple of text fields where the user can add info about the file in the frontend so it works in the backend?
Because I have no idea of how to make the frontend and backend work together in such a way.
Thanks for any help

Related

Requested data didn't came to database and nodejs post text is not showing afterwards submitting

I requested data, but it's neither shows error nor data was added to database.
const express = require("express");
const { hostname } = require("os");
const path = require("path")
const bodyparser = require("body-parser")
const mongoose = require('mongoose');
main().catch(err => console.log(err));
async function main() {
await mongoose.connect('mongodb://localhost/contactdance');
}
const app = express()
const port = 80;
//Defining mongoose scheme
const contactSchema = new mongoose.Schema({
name: String,
phone: String,
email: String,
address: String,
desc: String
});
const Contact = mongoose.model('Contact', contactSchema);
// EXPRESS SPECIFIC STUFF
app.use('/static', express.static('static')) // For serving static files
app.use(express.urlencoded())
// PUG SPECIFIC STUFF
app.set('view engine', 'pug') // Set the template engine as pug
app.set('views', path.join(__dirname, 'view')) // Set the views directory
//end point
app.get('/', (req, res)=>{
const params ={ }
res.status(200).render('home.pug', params);
})
app.get('/contact', (req, res)=>{
const params ={ }
res.status(200).render('contact.pug', params);
})
app.post('/contact', (req, res)=>{
var myData = new Contact(req.body);
myData.save().then(()=>{
res.send("This item has been saved to the database")
}).catch(()=>{
res.status(400).send("item was not saved to the databse")
})
})
app.listen(port, ()=>{
console.log(`The application started successfully on port ${port}`);
});
i expected to see text whether it succeeded or not but it didnt happen neither data was added.It didnt showed me error and i am like WTF.when i sew collections database contact was added but not data inside of it.

File upload makes Node JS unresponsive with Multer

I am using Multer Node JS package to upload files to my app sever , the code is basically typical upload file code
const express = require('express')
const multer = require('multer')
const upload = multer({ dest: 'uploads/' })
const app = express()
app.post('/profile', upload.single('avatar'), function (req, res, next) {
// req.file is the `avatar` file
// req.body will hold the text fields, if there were any
})
app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
// req.files is array of `photos` files
// req.body will contain the text fields, if there were any
})
But each time a file is being uploaded the Node server becomes unresponsive and frontend from other request doesnt receive any response from other APIs until the file is uploaded.
Whats the best way to tackle this ?
In your sample code, you must just send a response to the client by res.json() or res.end() :
const express = require('express');
const multer = require('multer');
const upload = multer({ dest: 'uploads/' });
const app = express();
app.post('/profile', upload.single('avatar'), function (req, res, next) {
// req.file is the `avatar` file
// req.body will hold the text fields, if there were any
res.status(204).end();
});
app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
// req.files is array of `photos` files
// req.body will contain the text fields, if there were any
res.status(204).end();
});
i can give you an example of how i implemented an imageupload in my app. it the code to upload a profile image for a user. i am also using multer middleware so it shoulder be similiar for you:
code is as follows:
// multer middleware:
const multer = require('multer');
const MIME_TYPE_MAP = {
'image/png': 'png',
'image/jpeg': 'jpg',
'image/jpg': 'jpg',
};
module.exports = storage = multer.diskStorage({
destination: (req, file, cb) => {
const isValid = MIME_TYPE_MAP[file.mimetype];
let error = new Error('invalid mime type');
if (isValid) {
error = null;
}
cb(error, 'images');
},
filename: (req, file, cb) => {
const name = file.originalname.toLowerCase().split(' ').join('-');
const ext = MIME_TYPE_MAP[file.mimetype];
if (name.includes('.' + ext)) {
cb(null, name)
} else {
cb(null, name + '.' + ext);
}
},
});
and here the code in the service handling the fileupload
// profile service in backend written in express
exports.uploadImage = (req, res, next) => {
const url = req.protocol + '://' + req.get('host');
profileRepository
.findOne({ _id: req.params.id })
.then((response) => {
const fetchedUser = response;
fetchedUser.imagePath = url + '/images/' + req.file.filename;
profileRepository
.updateOne({ _id: req.params.id }, fetchedUser)
.then((response) => {
return res.status(200).json({
message: 'profileimage updated',
});
})
.catch((error) => {
return res.status(500).json({
message: 'uploading image failed',
});
});
})
.catch((error) => {
return res.status(404).json({
message: 'fetching user failed',
});
});
};
then i use the middleware in my profile routes file like this:
// profile.routes.js
const express = require('express');
const ProfileController = require('./profileController');
const checkAuth = require('../middleware/checkAuth');
const router = express.Router();
const fileStorage = require('../middleware/fileStorage');
const multer = require('multer');
// imageUpload
router.post('/user/image/:id', checkAuth, multer({storage: fileStorage}).single('image'), ProfileController.image);
my Controller then calls the service function with the actual business logic like this:
// profile.controller.js
const profileService = require('./profileService');
exports.image = (req, res, next) => {
return profileService.uploadImage(req, res);
};
and finally my route is used by my app.js file like this:
// app.js
const express = require('express');
const profileRoutes = require('./profile/profileRoutes');
const app = express();
// set images path for saving images on server
app.use('/images', express.static(path.join('images')));
app.use('/api', profileRoutes);
module.exports = app;
i hope i was able to point you in the right direction with my example

How can I solve this : Cannot Get /upload error

I cloaned this code on youtube, it has Cannot GET /upload error.
I search google about this error, and many say it looks like app.get('/upload') missing problem.
But I don't know how to fix this code.
Can you tell me how to fix it?
const ipfsClient = require('ipfs-http-client');
const express = require('express');
const bodyParser = require('body-parser');
const fileupload = require('express-fileupload');
const fs = require('fs');
const ipfs = new ipfsClient(
{host:'localhost',
port:'5001',
protocol:'http'
});
const app = express();
app.engine('ejs',require('ejs').__express);
app.set('view engine','ejs');
app.use(bodyParser.urlencoded({extended:true}));
app.use(fileupload());
app.get('/',(req,res)=>{
res.render('home');
});
**app.post('/upload', (req,res)=>{
const file = req.files.file;
const fileName = req.body.fileName;
const filePath = 'files/' + fileName;
file.mv(filePath, async(err) => {
if (err){
console.log('Error failed to download the file');
return res.status(500).send(err);
}
const fileHash = await addFile(fileName, filePath);
fs.unlink(filePath, (err)=>{
if(err) console.log(err);
});
res.send(fileHash);
});
});**
*const addFile = async(fileName, filePath) =>{
const file = fs.readFileSync(filePath);
const fileAdded = await ipfs.add({path:fileName,content:file});
const fileHash = fileAdded[0].hash;
return fileHash;
};*
Since the /upload route is specified for POST method:
app.post('/upload', (req,res)=>{
there is no GET /upload route, which is the error you're getting.
So when calling your endpoint, you should change the method to POST

Stream multiple files with node js

I am trying to send multiple video files with express and mediaserver.
Is there a way to check if a file has finished streaming and then change the video to the next one?
Below is the express request.
So to clarify I can send a video over with the below request but I do not know how to change the file once it has finished streaming, I read that mediaserver is great at sending media files but there aren't any docs, so I could not find a way or a description of how to do this.
const express = require('express');
const app = express();
const ms = require('mediaserver');
app.get('/video', function(req, res){
const filename = 'sample1.mp4'
const filename1 = 'sample2.mp4'
ms.pipe(req, res, assetsPath + filename);
console.log ('[streaming video]: ' + filename);
});
app.listen(3000, function () {
console.log('Listening on port 3000...');
});
The best way to dynamically host files that I could find is to have a generic 'streaming' route and then pass the file as a query:
const express = require('express');
const app = express();
const ms = require('fs');
app.get('/stream', function(req,res){
var fileId = req.query.id,
file = __dirname + fileId;
fs.exists(file,function(exists){
if(exists) {
console.log("[Streaming:] %s", file);
var rstream = fs.createReadStream(file);
rstream.pipe(res);
} else {
console.log("[ERROR Streaming:] %s", file);
res.send("Playback 404");
res.end();
}
});
});
app.listen(3000, function () {
console.log('Listening on port 3000...');
});
You can then look through a directory and create a html string to send to the page, creating a button that streams the files on click:
var serverAddress = "http://localhost:3000"
var file = "sample.mp4"
stream = "<a href='" +serverAddress+ "/stream?id=" + file + "' target='_blank'><button class='btn btn-success'>Stream</button></a>";
res.send (stream)

How to retrieve path of image from mongoDB using Nodejs

I have uploaded the image in to a local directory using Busboy and passed
the path of the image to the MongoDB using Mongoose but now I unable to
retrieve the path
to display the image in my ejs view. I'm new to this nodejs. Please help me
to display the image.
Thank you Very much in Advance :)
var express = require('express'); //Express Web Server
var busboy = require('connect-busboy'); //middleware for form/file upload
var path = require('path'); //used for file path
var fs = require('fs-extra'); //File System - for file manipulation
var mongoose = require('mongoose');
var mongoClient = require('mongodb').mongoClient;
var objectId = require('mongodb').ObjectId;
var app = express();
app.use(busboy());
app.use(express.static(path.join(__dirname, 'public')));
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://localhost:27017/postname');
/* ==========================================================
Create a Route (/upload) to handle the Form submission
(handle POST requests to /upload)
Express v4 Route definition
============================================================ */
app.set('view engine','ejs');
app.use(express.static(__dirname + '/public'));
var nameSchema = mongoose.Schema({
newfile: Object,
path: String
});
var compileSchema = mongoose.model('foods', nameSchema);
app.get('/', function(req, res, next) {
res.render('index',{'title': 'New post app'});
});
app.route('/')
.post(function (req, res, next) {
var fstream;
req.pipe(req.busboy);
req.busboy.on('file', function (fieldname, file, filename) {
console.log("Uploading: " + filename);
//Path where image will be uploaded
fstream = fs.createWriteStream(__dirname + '/public/uploads/' + filename);
var dirname = path.join(__dirname + '/public/uploads/' + filename);
file.pipe(fstream);
//mongo save
var paths = new compileSchema({newfile : dirname, passReqToCallback: true});
paths.save(function(err){
if(err) throw err;
compileSchema.find({newfile: dirname}, (err, result) =>{
console.log();
return result;
});
});
fstream.on('close', function () {
console.log("Upload Finished of " + filename);
//where to go next
res.redirect('/profile');
});
});
});
app.get('/profile', (req, res)=>{
res.render('profile',{photo: req.result});
});
var server = app.listen(3030, function() {
console.log('Listening on port %d', server.address().port);
});
My Ejs file is :
<img src='<%= photo.newfile %>' >
This is the typical process of writing and reading from Mongodb using Mongoose. I have not checked whether your streaming and other things work fine but the db workflow would be better this way.
var express = require('express'); //Express Web Server
var busboy = require('connect-busboy'); //middleware for form/file upload
var path = require('path'); //used for file path
var fs = require('fs-extra'); //File System - for file manipulation
var mongoose = require('mongoose');
var mongoClient = require('mongodb').mongoClient;
var objectId = require('mongodb').ObjectId;
var app = express();
app.use(busboy());
app.use(express.static(path.join(__dirname, 'public')));
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://localhost:27017/postname');
/* ==========================================================
Create a Route (/upload) to handle the Form submission
(handle POST requests to /upload)
Express v4 Route definition
============================================================ */
app.set('view engine','ejs');
app.use(express.static(__dirname + '/public'));
//You can import your schema like this
const Name = require('./name');
var compileSchema = mongoose.model('foods', nameSchema);
app.get('/', function(req, res, next) {
res.render('index',{'title': 'New post app'});
});
//I have changed your route since it seems to be clashing with the above
app.post('/save' ,function (req, res, next) {
var fstream;
req.pipe(req.busboy);
req.busboy.on('file', function (fieldname, file, filename) {
console.log("Uploading: " + filename);
//Path where image will be uploaded
fstream = fs.createWriteStream(__dirname + '/public/uploads/' + filename);
file.pipe(fstream);
var dirname = path.join(__dirname + '/public/uploads/' + filename);
//mongo save
fstream.on('close', function () {
//You can either save to mongodb after streaming closes or while it is streaming but in this case I will do it after.
console.log("Upload Finished of " + filename);
//where to go next
//Declare your schema object here
let name = new Name({
newfile:'Whatever you want to store here',
path: path
});
//Save your declared schema like this
name.save((err) => {
if(err) throw err;
console.log(`saved : ${name}`);
//When you redirect here, it will go to /profile route
res.redirect('/profile');
});
});
});
});
app.get('/profile', (req, res)=>{
//You must retrieve from mongodb your object here if this is where you want the object to be
//{} empty query will find all objects in the table
Name.find({}, (err, result) => {
if(err) throw err;
//after everything was found, send it to front end
res.render('profile',{
photo: req.result,
//Now your 'compileSchema' object is available at front end as 'result' object
result:result
});
});
});
var server = app.listen(3030, function() {
console.log('Listening on port %d', server.address().port);
});
name.js (create one schema js file for each table you will be working with)
let mongoose = require('mongoose');
let Schema = mongoose.Schema;
let compileSchema = new Schema({
newfile: Object,
path: String
});
let Compile = mongoose.model('Compiles', compileSchema);
module.exports = Compile;
Check first that you are receiving and streaming file correctly. If you are, it must work fine. Also, I don't know why you want to save a newfile:object field but all you really need to do is save the path to the image file then retrieve it where you need to use the image and use the path as the <img src='path'> Refer to the comments.

Categories

Resources