I'm trying to figure out why my data hasn't been saving in MongoDB, despite calling the .save() method. I'm aware that this is an asynchronous process, but as you can see below, I set up a callback using .then() - which executes without error. The target database has a single empty collection in it, so I was expecting the data to appear there or in a new collection, neither of which happened. Here's the code for my index.js file:
const express = require('express');
const mongoose = require('mongoose');
const { body, validationResult } = require('express-validator/check');
const router = express.Router();
const Registration = mongoose.model('Registration');
router.get('/', (req, res) => {
res.render('form', { title: 'Registration Form'});
});
router.post('/',
[body('name')
.isLength(1)
.withMessage('Please enter a name.'),
body('email')
.isLength(1)
.withMessage('Please enter an email address.')
],
(req, res) => {
//console.log(req.body);
const errors = validationResult(req);
if(errors.isEmpty)
{
const registration = new Registration(req.body);
//registration.markModified('collection_1');
registration.save()
.then(() => { res.send('Thank you for your registration!'); })
.catch(() => { res.send('Sorry! Something went wrong.'); });
} else {
// re-renders form with error message
res.render('form', {
title: 'Registration form',
errors: errors.array(),
data: req.body,
});
}
});
module.exports = router;
Let me know if any other files would be useful. Any assistance would be greatly appreciated.
EDIT: Here's my start.js file.
require('dotenv').config();
const mongoose = require('mongoose');
require('./models/Registration');
mongoose.connect(process.env.DATABASE, { useMongoClient: true });
mongoose.Promise = global.Promise;
mongoose.connection
.on('connected', () => {
console.log(`Mongoose connection open on ${process.env.DATABASE}`);
})
.on('error', (err) => {
console.log(`Connection error: ${err.message}`);
});
const app = require('./app');
const server = app.listen(3000, () => {
console.log(`Express is running on port ${server.address().port}`);
});
Related
TypeError: Post is not a constructor
owoce.js
const express = require('express');
const router = express.Router();
const Post = require('../models/owoc');
router.get('/', (req,res) => {
res.send('we are on owoce');
//try {
// const owoce = await Owoc.find()
// res.json(owoce)
// }catch (err){
// res.status(500).json({ message: err.message })
// }
})
// router.get('/jablka', (req,res) => {
// res.send('we are on jablka');
//});
router.post('/', (req,res) => {
const owoc = new Post({
rodzaj: req.body.rodzaj,
kolor: req.body.kolor
})
owoc.save()
.then(data =>{
res.json(data);
})
.catch(err => {
res.json({message: err});
});
});
module.exports = router;
owoc.js it includes schema
const mongoose = require('mongoose');
const OwocSchema = new mongoose.Schema({
rodzaj: {
type: String,
required: true
},
kolor: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
}
});
//mongoose.Schema({
// username: String,
// password: String
//})
mongoose.exports = mongoose.model('Owoc', OwocSchema)
I am not sure what the problem is after looking at simmilar anwseres here
i dont see what should be changed
const Post = require('../models/owoc');
server.js adding it coz it may be usefull to troubleshoot
const express = require('express')
//const req = require('express/lib/request');
//const res = require('express/lib/response');
const app = express()
const mongoose = require('mongoose')
const bodyParser = require('body-parser');
require('dotenv/config');
app.use(bodyParser.json());
//const db = mongoose.connection('mongodb://localhost/sklep')
//MIDDLEWARES
app.use('/posts', ()=> {
console.log('This is a middleware');
});
//IMPORT ROUTES
const owoceRoute = require('./routes/owoce');
app.use('/owoce', owoceRoute);
//ROUTES
app.get('/', (req,res) => {
res.send('we are on home');
});
//connect to DB
mongoose.connect(
process.env.DB_CONNECTION ,mongoose.set('strictQuery', true), ()=> {
console.log('Connected to DB!!:))');
}); //{ useNewUrlParser: true})
//how to lisen to server
///db.on('error',(error) => console.error(error))
///db.once('open',() => console.log('connected to database'))
//db.on('connected', () => console.log('Connected to database'))
app.listen(3000, () => console.log('server started'))
I am adding screenshot and server code app despite not being sure if it will be any help
here is the screen from Postman
try this:
router.post('/create', async (req,res) => {
const owoc = await Owoc.create({
rodzaj: req.body.rodzaj,
kolor: req.body.kolor
})
.then(data =>{
res.json(data);
})
.catch(err => {
res.json({message: err});
});
});
I am using node and express server to run the mongoDb. For connection and schema I am using mongoose. i successfully connect the database and able to post the data by using postman but problem is it does not show the expected query. Mongodb returns me only the id not the query which is name and description
Here is models
const mongoose = require("mongoose");
const { Schema } = mongoose;
const form = new Schema(
{
name: { type: String },
description: { type: String }
},
{
timestamps: true
}
);
const formSubmit = mongoose.model("formSubmit", form);
module.exports = formSubmit;
This is my express server
const express = require("express");
const port = 5000;
const cors = require("cors");
const morgan = require("morgan");
const app = express();
const formSubmit = require("./models");
const mongoose = require("mongoose");
app.use(cors());
app.use(morgan("dev"));
mongoose
.connect(
"url",
{
useUnifiedTopology: true,
useNewUrlParser: true
}
)
.then(() => console.log("DB Connected!"))
.catch(err => {
console.log(err);
});
//get method
app.get("/show", async (req, res) => {
try {
const entrries = await formSubmit.find();
res.json(entrries);
} catch (error) {
console.log(error);
}
});
//post method
app.post("/post", async (req, res, next) => {
try {
const logs = new formSubmit(req.body);
const entry = await logs.save();
res.json(entry);
} catch (error) {
if (error.name === "ValidationError") {
res.status(422);
}
next(error);
}
});
app.listen(port, () => {
console.log(`Server is running port ${port}`);
});
I think the problem is you don't correctly save the documents to the collection, so when you retrieve them only _id fields display.
To be able to read request body, you need to add express.json() middleware to your server.js.
app.use(express.json());
I'm using the MERN stack to build an application for the first time.
In order to log HTTP requests I use "morgan".
I managed to send data to mongodb which seems to be working fine. The problem is that my post request is not coming through. It says "pending" for 4 minutes, then fails.
Here's what I think is the relevant part of my code:
"server.js":
const express = require("express");
const mongoose = require("mongoose");
const morgan = require("morgan");
const path = require("path");
const cors = require("cors");
const app = express();
const PORT = process.env.PORT || 8080;
const routes = require("./routes/api");
const MONGODB_URI =
"...";
mongoose.connect(MONGODB_URI || "mongodb://localhost/app", {
useNewUrlParser: true,
useUnifiedTopology: true
});
mongoose.connection.on("connected", () => {
console.log("Mongoose is connected.");
});
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cors());
app.use(morgan("tiny"));
app.use("/api", routes);
app.listen(PORT, console.log(`Server is starting at ${PORT}`));
Then I've put my routes into another file "api.js":
const express = require("express");
const router = express.Router();
const Lane = require("../models/lanes");
router.get("/", (req, res) => {
Lane.find({})
.then(data => {
res.json(data);
console.log("Get request successful!");
})
.catch(error => {
console.log("Error: ", error);
});
});
router.post("/save", (req, res) => {
const data = req.body;
const newLane = new Lane();
newLane.collection.insertMany(data, err => {
if (err) {
console.log(err);
} else {
console.log("Multiple docs inserted");
}
});
});
module.exports = router;
I'm using axios to send the request. This happens after submitting a form within my application.
reducer function:
const reducer = (state, action) => {
switch (action.type) {
case "add":
axios({
url: "http://localhost:8080/api/save",
method: "POST",
data: [...state, { id: uuid(), title: action.title, tasks: [] }]
})
.then(() => {
console.log("Data has been sent to the server");
})
.catch(() => {
console.log("Internal server error");
});
return [...state, { id: uuid(), title: action.title, tasks: [] }];
The reducer is being used by my context provider component, which looks like this:
export function LanesProvider(props) {
const [lanes, dispatch] = useReducer(reducer, defaultLanes);
return (
<LanesContext.Provider value={lanes}>
<DispatchContext.Provider value={dispatch}>
{props.children}
</DispatchContext.Provider>
</LanesContext.Provider>
);
}
The "add" method inside my reducer is being called when submitting a form inside another component.
Please let me know if I can add anything to my question that would help.
Thank you in advance!
you are not sending any response back to client. Try to modify post method like
router.post("/save", (req, res) => {
const data = req.body;
const newLane = new Lane();
newLane.collection.insertMany(data, err => {
if (err) {
console.log(err);
res.send(err)
} else {
console.log("Multiple docs inserted");
res.send("Multiple docs inserted")
}
});
});
On localhost:5000/posts my data is successfully showing but if I do the same thing in Heroku: https://rest-in-peep.herokuapp.com/posts I get an application error. https://rest-in-peep.herokuapp.com/ works fine and I deployed it through Heroku GIT. I made sure to config my environmental vars in Heroku and added a Procfile but I am still getting this application error. I've been trying all day to figure this out but what I expect to happen is if I type in https://rest-in-peep.herokuapp.com/posts, I will get all the data that is being stored on my MongoDB database.
app.js file
const http = require("http");
const express = require("express");
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const cors = require("cors");
require("dotenv/config");
const app = express();
const server = http.createServer(app);
//Middlewares
app.use(cors());
app.use(bodyParser.json());
//Import Routes
const postsRoute = require("./routes/posts");
app.use("/posts", postsRoute);
//ROUTES
app.get("/", (req, res) => {
res.send("We are on home");
});
//Connect to DB
mongoose.connect(
process.env.DB_CONNECTION,
{ useNewUrlParser: true },
() => console.log("connected to MongoDB")
);
//How do we start listening to the server
server.listen(process.env.PORT || 5000, () => {
console.log("App now running on PORT");
});
routes>
posts.js
const express = require("express");
const Post = require("../models/Posts");
const router = express.Router();
//GETS BACK ALL THE POSTS
router.get("/", async (req, res) => {
try {
const posts = await Post.find();
res.json(posts);
} catch (err) {
res.json({ message: err });
}
});
//SUBMITS A POST
router.post("/", async (req, res) => {
console.log(req);
const post = new Post({
quote: req.body.quote
});
try {
const savedPost = await post.save();
res.json(savedPost);
} catch (err) {
res.json({ message: err });
}
});
//SPECIFIC POST
router.get("/:postId", async (req, res) => {
try {
const post = await Post.findById(req.params.postId);
res.json(post);
} catch (err) {
res.json({ message: err });
}
});
//Delete Post
router.delete("/:postId", async (req, res) => {
try {
const removedPost = await Post.remove({ _id: req.params.postId });
res.json(removedPost);
} catch (err) {
res.json({ message: err });
}
});
//Update a post
router.patch("/:postId", async (req, res) => {
try {
const updatedPost = await Post.updateOne(
{ _id: req.params.postId },
{
$set: { quote: req.body.quote }
}
);
res.json(updatedPost);
} catch (err) {
res.json({ message: err });
}
});
module.exports = router;
gitignore
/node_modules
models>Posts.js
const mongoose = require("mongoose");
const PostSchema = mongoose.Schema({
quote: {
type: String,
required: true
}
});
module.exports = mongoose.model("Posts", PostSchema);
I'm trying to create my first MongoDB app with Express & Angular & Azure Cosmos DB.
Here is my js files:
hero.model.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const heroSchema = new Schema({
id: {
type: Number,
required: true,
unique: true
},
name: String
}, {
collection: 'Heroes'
})
const Hero = mongoose.model('Hero', heroSchema);
module.exports = Hero;
mongo.js
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
const env = require('./env/environment');
const mongoUri =
mongodb:`${env.accountName}:${env.key}#${env.accountName}
.documents.azure.com:10255/?ssl=true`
function connect() {
mongoose.set('debug', true);
return mongoose.connect(mongoUri)
}
module.exports = {
connect,
mongoose
};
index.js
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const routes = require('./routes');
const root = './';
const port = process.env.PORT || '3000';
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(root, 'docs')));
app.use('/api', routes);
app.get('*', (req, res) => {
res.sendFile('docs/index.html', {root});
});
route.js
const express = require('express');
const router = express.Router();
const heroService = require('./hero.service');
router.get('/heroes', (req, res) => {
heroService.getHeroes(req, res);
});
router.post('/hero', (req, res) => {
heroService.postHero(req, res);
});
router.put('/hero/:id', (req, res) => {
heroService.putHero(req, res);
});
router.delete('/hero/:id', (req, res) => {
heroService.deleteHero(req, res);
});
module.exports = router;
app.listen(port, () => console.log(`API running on
localhost:${port}`));
hero.service.js
const Hero = require('./hero.model');
require('./mongo').connect();
function getHeroes(req, res) {
const docquery = Hero.find({});
docquery
.exec()
.then(heroes => {
res.status(200).json(heroes);
})
.catch(error => {
res.status(500).send(error);
return;
});
}
function postHero(req, res) {
const originalHero = {
id: req.body.id,
name: req.body.name
};
const hero = new Hero(originalHero);
hero.save(error => {
if (checkServerError(res, error)) return;
res.status(201).json(hero);
console.log('Hero created successfully!');
});
}
function checkServerError(res, error) {
if (error) {
res.status(500).send(error);
return error;
}
}
function putHero(req, res) {
const originalHero = {
id: parseInt(req.params.id, 10),
name: req.body.name
};
Hero.findOne({
id: originalHero.id
}, (error, hero) => {
if (checkServerError(res, error)) return;
if (!checkFound(res, hero)) return;
hero.name = originalHero.name;
hero.save(error => {
if (checkServerError(res, error)) return;
res.status(200).json(hero);
console.log('Hero updated successfully!');
});
});
}
function deleteHero(req, res) {
const id = parseInt(req.params.id, 10);
Hero.findOneAndRemove({
id: id
})
.then(hero => {
if (!checkFound(res, hero)) return;
res.status(200).json(hero);
console.log('Hero deleted successfully!');
})
.catch(error => {
if (checkServerError(res, error)) return;
});
}
function checkFound(res, hero) {
if (!hero) {
res.status(404).send('Hero not found.');
return;
}
return hero;
}
module.exports = {
getHeroes,
postHero,
putHero,
deleteHero
};
It only works when I POST a new hero for the first time and a second time gives me an error:
E11000 duplicate key error collection: admin.Heroes Failed _id or unique key constraint.
Please help!!
Thanks.
I know it's been a while but I've encountered the same problem. The solution is avoid using the field name id, rename it to UID or something. Once you done that you have to remove the entire collection and restart.
If you are following the Microsoft CosmosDB Angular tutorial, you can clone the repo below and test it on your local.
https://github.com/Azure-Samples/angular-cosmosdb
If you are using a newer version of mongoose you have to upgrade the connection string below.
//useMongoClient: true
useNewUrlParser: true