I am developing a web page with node.js and express. I developed a form where users can fill their details and upload their image. The image file is expected to be stored inside a directory while the path is stored in the database.
I am using Node.js with mongodb database. The image is successfully stored in the expected directory but the path is not stored inside the database instead of the path, I found the code to store the path inside the database (/posts/${image.name} for every of the file uploaded. please how do I achieve this?
{
//Index.js
const path = require('path');
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const Post = require('./database/models/Post');
const fileUpload = require("express-fileupload");
const app = new express();
mongoose.connect('mongodb://localhost/node-js-test-blog', { useNewUrlParser: true })
app.use(express.static('public'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(fileUpload());
//the route responsible for storing the image in posts directory and the path in the database
app.post('/posts/store', (req, res) => {
const { image } = req.files
image.mv(path.resolve(__dirname, 'public/posts', image.name), (error) => {
Post.create({
...req.body,
image: '/posts/${image.name}'//this code is what I get in the database instead of the path
}, (error, post) => {
res.redirect("/");
});
})
});
app.listen(4000, () => {
console.log("application listening on port 4000")
})
}
//model
const mongoose = require('mongoose');
//collections represents entities in the application e.g users, posts, etc
//schema represents how to structure in the collections
const PostSchema = new mongoose.Schema({
description: String,
title: String,
content: String,
username: String,
image: String,
createdAt: {
type: Date,
default: new Date()
}
});
//the model itself is what will communicate with the database
const Post = mongoose.model('Post', PostSchema);
module.exports = Post;
}
//the code to display the (image) view from the database using node.js directive
<style="background-image: url('{{post.image}}')">
}
You need to use backticks when using ${}, otherwise the string is interpreted literally:
Change this:
image: '/posts/${image.name}'
To this:
image: `/posts/${image.name}`
Related
problem with saving to MongoDB database
This is my second time trying to post to a database, still new to it. I am receiving string from a html form and trying to save into the database. I have connected to mongodb successfully, setup my post route, setup my model and now trying to send the http request to save it to db. before setting up the model, I was able to console.log the data I received from my form. but after setting up the model and trying to get the route to save it to db, it just hangs. If i comment out the main.save(), and console.log(main), alll I get back is an _id.
i cant figure out where im going wrong with it
index.js
const express = require('express')
const path = require('path')
const routes = require('../routes/routes')
const app = express()
const port = 3000
app.use(express.json())
app.use(express.urlencoded({ extended: false }))
app.use(express.static(path.join(__dirname, '../public')))
app.use(routes)
app.listen(port, () => {
console.log('Server is up on port ' + port)
})
routes
const express = require('express')
const Main = require('../src/model')
const router = new express.Router()
router.post('/', async (req, res) => {
const main = new Main(req.body)
console.log(main)
try{
await main.save()
res.status(201).send(main)
} catch (e) {
res.status(400).send(e)
console.log('Not working!')
}
})
module.exports = router
model
const mongoose = require('mongoose')
const Main = mongoose.model('Main', {
total_check: {
type: String
}
})
module.exports = Main
receiving an _id, but hanging on .save()
This is because you are passing whole req.body to the database. Change this const main = new Main(req.body) to this
let main= new Main({
total_check:req.body.total_check
});
Just make sure you are receiving correct data from your frontend end or Postman.
Also save returns a callback so handle that as well
main.save((err,main)=>{
if(err) {console.log(err) }
else { res.status(201).send(main) }
});
i made a very simple api using express.js. Here's the code:
var express = require('express');
var app = express();
var morgan = require('morgan');
var UserModel = require('../Models/User')
app.use(morgan('short'));
app.use(express.json());
app.get('/getAll', (req, res) => {
res.status(200).json({auth: true});
})
app.post('/addUser', (req, res) => {
const { name, email, password } = req.body;
UserModel.create({name, email, password}, (err, user) => {
if(err) return res.status(500).end({auth: false})
res.status(200).end({user});
});
});
module.exports = app;
And here's the userModel:
const mongoose = require("mongoose")
const Schema = mongoose.Schema;
const UserSchema = new Schema(
{
name: String,
email: String,
password: String,
},
{timestamps: false}
);
mongoose.model("User", UserSchema);
module.exports = mongoose.model("User");
This is the main server.js file:
var express = require('express');
var app = express();
const AuthController = require("./Controllers/AuthController");
const PORT = 3001;
app.use("/api/auth", AuthController);
app.listen(PORT, () => console.log(`Listening on port ${PORT}..`))
This is the db.js file:
const mongoose = require('mongoose');
const dbRoute = "mongodb://<user>:<password>#<stuff>/nodejs-db";
mongoose.connect(
dbRoute,
{useNewUrlParser: true}
);
So here's the problem. when i try to make a request to this api using Insomnia, the requests doesn't end. Basically Insomia starts sending the request and i have to wait like 20 secs until i get something on my express terminal. If i end the request manually i get this:
::ffff:127.0.0.1 - POST /api/auth/addUser HTTP/1.1 - - - - ms
I tried looking online but couldn't find anything useful.
I come from a django backgrond. I'm new to Node and Express js.
Edit:
The problem is only with the posts requests because whenever i make a get request it returns immediately {auth: true}.
Change your .end() to .send()
app.post('/addUser', (req, res) => {
const { name, email, password } = req.body;
UserModel.create({name, email, password}, (err, user) => {
if(err) return res.status(500).send({auth: false})
res.status(200).send({user});
});
});
I solved this problem.
Apparently the problem was that my db connection was on another file.
All i did was to move the content from the db.js file to my server.js file.
I forgot to include my db file.
I'm working on a node.js app, and every time I run this code it pops up a reference error saying that Post is not defined. When I put the post route into app.js instead of submit.js, it works fine. That leads me to believe it's because submit.js doesn't "see" the model defined in app.js. I'm very new to web development, so it's probably something pretty basic that I'm missing.
app.js
var express = require('express');
var mongoose = require('mongoose');
var submitRouter = require('./routes/submit');
var app = express();
mongoose.Promise = global.Promise;
mongoose.connect("mongodb://localhost:27017/posts");
//Mongoose Schema
var postSchema = new mongoose.Schema({
username: String,
date: Date,
title: String,
link: String,
text: String,
votes: Number,
community: String
});
var Post = mongoose.model("Post", postSchema);
app.use('/submit', submitRouter);
module.exports = app;
submit.js
var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');
router.post('/', function(req, res, next){
var newPost = new Post(req.body);
newPost.save()
.then(item => {
res.json(newPost);
})
.catch(err => {
res.status(400).send("unable to save to database");
});
});
module.exports = router;
Post is not defined It’s because you don’t have mongoose schema defined in submit.js like you did in App.js.
You are creating an instance to Post using new Post but the Post doesn’t exist in submit.js
I would recommend you to put your schema in separate file and import it in submit.js
Create a folder called schema and inside this folder create a file name called PostSchema.js
PostSchema.js
var mongoose = require('mongoose');
//Mongoose Schema
var postSchema = new mongoose.Schema({
username: String,
date: Date,
title: String,
link: String,
text: String,
votes: Number,
community: String
});
var Post = mongoose.model("Post", postSchema);
module.exports = Post;
Import post schema in submit.js
var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');
var Post = require('./schema/PostSchema.js');
router.post('/', function(req, res, next){
var newPost = new Post(req.body);
newPost.save()
.then(item => {
res.json(newPost);
})
.catch(err => {
res.status(400).send("unable to save to database");
});
});
module.exports = router;
By the way, it’s not an issue with Express Router.
I am developing REST API using nodeJS, express, mongoose etc with mongodb. I am uploading file and saving it to a folder using multer. Now I want to save the path of the file to a mongodb document.
However, I am saving data to mongodb using mongoose schema. First I created the model. When a post request is made, I read it using bodyParser (req.body) and save this object by creating new instance or more shortcut.
Product.create(req.body).then(function(product){
res.send(product);
}).catch(next);
But when I am using multer to upload a file and want to save the path to the model I cant do it using create() function. So what is the way ??
In the MongoDB we can store single or multiple images. For storing multiple images I am using productPictures array.
1: First, create the Product model
const mongoose = require('mongoose');
const productSchema = new mongoose.Schema({
name: {
type: String,
required: true,
trim: true,
},
productPictures: [{ img: { type: String } }],
});
module.exports = mongoose.model('Product', productSchema);
2: Create the product controller
const Product = require('../models/product');
exports.createProduct = (req, res) => {
const { name} = req.body;
let productPictures = [];
if (req.files.length > 0) {
productPictures = req.files.map((file) => {
return { img: file.filename };
});
}
const product = new Product({
name,
productPictures,
});
product.save((error, product) => {
if (error) return res.status(400).json({ error });
if (product) {
res.status(201).json({ product });
}
});
};
3: Create products route file
I am using nanoid to generate a unique name for images
Create uploads folder inside src folder
const express = require('express');
const path = require('path');
const multer = require('multer');
const { nanoid } = require('nanoid');
const { createProduct } = require('../controllers/product');
const router = express.Router();
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, path.join(path.dirname(__dirname), 'uploads'));
},
filename: function (req, file, cb) {
cb(null, nanoid() + '-' + file.originalname);
},
});
const upload = multer({ storage: storage });
router.post(
'/products/create',
upload.array('productPicture'), // for storing single image : upload.single('productPicture')
createProduct
);
module.exports = router;
4: Create server.js file
const env = require('dotenv');
const express = require('express');
const mongoose = require('mongoose');
const app = express();
// routes
const productRoutes = require('./routes/product');
env.config();
mongoose
.connect(`${process.env.MONGO_URI}`, {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
})
.then(() => {
console.log('Database connected');
});
// Body parser (You can you **body-parser**)
app.use(express.json());
app.use('/api', productRoutes);
app.listen(process.env.PORT, () => {
console.log(`Server is running on port ${process.env.PORT}`);
});
5: Finally you can create product using postman
Here you can upload the image into some destination you want, this is for the reference for more details information including how to access stored images in Mongodb and you can see the documentation here about multer.
express = require('express')
, router = express.Router()
, MongoClient = require('mongodb').MongoClient
, ObjectId = require('mongodb').ObjectId
, fs = require('fs-extra')
// Your mongodb or mLabs connection string
, url = 'mongodb://username:password#yourinstanced.mlab.com:29459/yourdb'
, multer = require('multer')
, util = require('util')
, upload = multer({limits: {fileSize: 2000000 },dest:'/uploads/'})
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
if (req.file == null) {
// If Submit was accidentally clicked with no file selected...
)} else {
MongoClient.connect(url, function(err, db){
// this landing will give you any option of file information that you can collect
console.log('landing here', req.file)
// read the img file from tmp in-memory location
var newImg = fs.readFileSync(req.file.path);
// encode the file as a base64 string.
var encImg = newImg.toString('base64');
// define your new document
var newItem = {
contentType: req.file.mimetype,
size: req.file.size,
name: req.file.originalname,
path: req.file.path
};
db.collection('yourcollectionname')
.insert(newItem, function(err, result){
if (err) { console.log(err); };
var newoid = new ObjectId(result.ops[0]._id);
fs.remove(req.file.path, function(err) {
if (err) { console.log(err) };
res.send(newItem);
});
});
});
}});
If using multer you will get uploaded files path in req.file.path and you just need to save that in your database.
I am new to Node.js and programming in general. This is my first server side language and I need your help. I do have html/css/javascript experience. I also know how to serve up html pages via NodeJS using FileSystem and the request.url stream.
*Question:*
How do you query and display data from Mongo DB into an html page without using Express or any other framework? Pure Node.JS /Javascript**
I rather not use Express because I am trying to master Node.JS first.
I tried studying PHP's way of doing it, and found their process to to be like this :
Connect to database:
$con=mysqli_connect("example.com","peter","abc123","my_db");
Query Database:
$result = mysql_query("SELECT * FROM names");
Display Results :
<?php echo $result; ?>
How does Node.js connect / query / and display from database to front end? without using frameworks like EXPRESS
Try this example, it contains one route (http://localhost:3000/test) which you can request from your frontend and it will return json data taken from the mongodb using mongoose.
Test.js
var express = require("express"),
app = express(),
bodyparser = require("body-parser"),
mongoose = require("mongoose");
const router = express.Router();
app.use(bodyparser.json());
mongoose.connect('mongodb://localhost:27017/test');
const connection = mongoose.connection;
connection.once('open', () => {
console.log('MongoDB connected successfully');
})
var schema = new mongoose.Schema({
name: String,
value: String
})
var data=mongoose.model("testdata", schema);
router.route('/test').get((req, res) => {
data.find((err, testdata) => {
if (err)
console.log(err)
else
res.json(testdata);
})
})
app.use('/', router);
app.listen(3000, function () {
console.log('server started on port 3000');
});
here is my code which I have run in my localhost, and it is working fine.
Code
const http = require('http');
const port = 8080;
const hostname = 'localhost';
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/testDB', {
useCreateIndex: true,
useNewUrlParser: true
});
var schema = new mongoose.Schema({
firstName: String,
lastName: String
})
var userSchema = mongoose.model("user", schema);
http.createServer((req, res) => {
userSchema.find().then((result, err) => {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({status: 200, message: 'data retrive
successfully' data : result}));
})
}).listen(port, () => {
console.log(`your server are listing http://${hostname}:${port}`);
})
I hope it will help you, To create a server without using the express framework in nodeJS.
To query mongo with node you are most definetly going to need some sort of node-module such as node-mongo-db-native (https://github.com/mongodb/node-mongodb-native). You can't do it with just node core...
Here is an example of querying a mongodb using node-mongo-db-native module docs...
var MongoClient = require('mongodb').MongoClient
, format = require('util').format;
MongoClient.connect('mongodb://127.0.0.1:27017/test', function(err, db) {
if(err) throw err;
var collection = db.collection('test_insert');
collection.insert({a:2}, function(err, docs) {
collection.count(function(err, count) {
console.log(format("count = %s", count));
});
// Locate all the entries using find
collection.find().toArray(function(err, results) {
console.dir(results);
// Let's close the db
db.close();
});
});
})