MongoDB and Cosmos DB key error collection - node.js

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

Related

0 I am working on NodeJs application it's shop application. I am trying to save posts in database and I am getting this error after submitting form:

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});
});
});

Access Returned Object Properties from Router

I start my server using nodemon which starts the server on localhost 8080
I go to localhost:8080/api which returns:
[{"date":"1587946153337","_id":"5ea622b6334c4de9fa307b20","post":"This is the first post!","__v":0},{"date":"1603312852793","_id":"5f909d49d75c9b1ec2e39ee7","post":"this is a test","__v":0},{"date":"1603313042345","_id":"5f909dea89eeee2d40e933c6","post":"this is a second test post","__v":0},{"date":"1603483744050","_id":"5f9338b12e575d3935b0b16b","post":"hiiii","__v":0},{"date":"1603483572093","_id":"5f9338b264236f36c48c3a60","post":"e","__v":0},{"date":"1604349323678","_id":"5fa06dcd59aeeba1e1845c0f","post":"was","__v":0}]
How can I gain access to the properties that are returned? For example, I want to display the post property as HTML.
The object that seems to hold the properties is data from api.js
const router = express.Router();
const mongoose = require('mongoose');
const https = require("https");
const Post = require('../models/post'); // This is the model to use
// Routes
router.get('/', (req, res) => {
Post.find( { })
.then((data) => {
console.log('Data: ', data);
const log = res.json(data);
//console.log(log);
})
.catch((error) => {
console.log('Error: ', daerrorta);
});
});
Here is my server.js
const express = require('express');
const mongoose = require('mongoose');
const morgan = require('morgan');
const path = require('path');
const app = express();
const PORT = process.env.PORT || 8080;
const routes = require('./routes/api');
const postString = "test";
const commentString = "test";
const profString = "test";
const univString = "test";
// MONGODB ACCOUNT INFO:
// Usermame: MyCampusAdmin
// Password: AdminForMyCampus
// MongoDB URI
const MONGODB_URI = 'mongodb+srv://MyCampusAdmin:AdminForMyCampus#mycampus-whyic.mongodb.net/MyCampus?retryWrites=true&w=majority';
mongoose.connect(MONGODB_URI || 'mongodb://localhost/MyCampus', {
useNewUrlParser: true,
useUnifiedTopology: true
});
mongoose.connection.on('connected', () => {
console.log('Mongoose is connected');
});
// Data parsing
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
// HTTP request logger
app.use(morgan('tiny'));
app.use('/api', routes);
//function makePost(p) {
// p = postString;
// postData
// const postData = {
// post: p,
// univID: 1,
// numLikes: 0
// };
// Post Save
// const newPost = new Post(postData); // Instance of the new model
// Post Save
// newPost.save((error) => {
// if (error) {
// console.log('Something went wrong with post save');
// }
// else {
// console.log('Post data has ben saved');
// }
// });
//}
function makeComment(c) {
c = commentString;
// commentData
const commentData = {
comment: c,
postID: 1,
numLikes: 0
};
// Comment Save
const newComment = new Comment(commentData);
// Comment Save
newComment.save((error) => {
if (error) {
console.log('Something went wrong with comment save');
}
else {
console.log('Comment data has ben saved');
}
});
}
function addProf(pr) {
pr = profString;
// profData
const profData = {
name: pr,
univID: 1,
department: "SE",
classes: "Applied Research"
};
// Prof Save
const newProf = new Prof(profData);
// Prof Save
newProf.save((error) => {
if (error) {
console.log('Something went wrong with prof save');
}
else {
console.log('Prof data has ben saved');
}
});
}
function addUniv(u) {
u = univString;
// univData
const univData = {
university: u
};
// University Save
const newUniv = new University(univData);
// Universoty Save
newUniv.save((error) => {
if (error) {
console.log('Something went wrong with university save');
}
else {
console.log('University data has ben saved');
}
});
}
// COMMENT SET UP
// Comment Schema Declaration
const SchemaComment = mongoose.Schema;
// Comment Schema
const CommentSchema = new SchemaComment ({
comment: String,
postID: Number,
date: {
type: String,
default: Date.now()
},
numLikes: Number,
});
// Comment Model
const Comment = mongoose.model('Comment', CommentSchema);
//PROF SET UP
// Prof Schema Declaration
const SchemaProf = mongoose.Schema;
// Professor Schema
const ProfSchema = new SchemaProf ({
name: String,
univID: Number,
department: String,
classes: String
});
// Professor Model
const Prof = mongoose.model('Professor', ProfSchema);
// UNIV SET UP
// University Schema Declaration
const SchemaUniv = mongoose.Schema;
// University Schema
const UnivSchema = new SchemaUniv ({
university: String,
});
// University Model
const University = mongoose.model('University', UnivSchema);
//TESTING FUNCTIONS
// makePost(postString);
// makeComment(commentString);
// addProf(profString);
// addUniv(univString);
app.listen(PORT, console.log(`Server is starting at ${PORT}`));
//app.listen(3000, function(){
// console.log("Server 3000");
//});
/*
app.get("/", function(req, res){
res.sendFile(__dirname + "/AccountSetUp.jsx");
});
app.post("/", function(req, res){
res.sendFile(__dirname + "/AccountSetUp.jsx");
});
*/
Here is my api.js
const router = express.Router();
const mongoose = require('mongoose');
const https = require("https");
const Post = require('../models/post'); // This is the model to use
// Routes
router.get('/', (req, res) => {
Post.find( { })
.then((data) => {
console.log('Data: ', data);
const log = res.json(data);
//console.log(log);
})
.catch((error) => {
console.log('Error: ', daerrorta);
});
});
router.get("/", function(req, res){
https.get(Post, function(response){
console.log(response.statusCode);
})
res.send("hello")
})
router.post('/save', (req, res) => {
console.log('Body: ', req.body);
const data = req.body;
const newPost = new Post(data);
newPost.save((error) => {
if (error) {
res.json({ msg: 'Sorry, internal server errors'});
}
else {
// Post
res.json({
msg: 'Your data has been saved!!'
});
}
});
});
router.get('/name', (req, res) => {
const data = {
username: 'name',
age: 20
};
res.json(data);
});
module.exports = router;
This is all the code I have for the component that is to fetch and render the data. I'm not sure how to access the data returned from router.get in this component.
DisplayPost.tsx
import { router } from "../routes/api";
export const DisplayPost = () => {
return(
<>
<div>Welcome</div>
</>
)
}

Mongodb query does not the show the expect result

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());

Heroku - Request timed out for fetching request

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);

Mongoose only saves _id and _v

This is indeed a duplicate question however there is no answer.
The problem is that when I save a new record with mongoose through a post request, all that's saved is something like this:
{ "_id" : ObjectId("5d11590975c82f216eaa4712"), "__v" : 0 }
I am following this tutorial so the code should work fine, but regardless here it is:
the mongoose schema:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
let Todo = new Schema({
todo_description: {
type: String
},
todo_responsible: {
type: String
},
todo_priority: {
type: String
},
todo_completed: {
type: Boolean
}
});
module.exports = mongoose.model('Todo', Todo);
the code:
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const cors = require('cors');
const mongoose = require('mongoose');
const todoRoutes = express.Router();
const PORT = 4000;
let Todo = require('./todo.model');
app.use(cors());
app.use(bodyParser.json());
mongoose.connect('mongodb://127.0.0.1:27017/todos', { useNewUrlParser: true });
const connection = mongoose.connection;
connection.once('open', function() {
console.log("MongoDB database connection established successfully");
})
todoRoutes.route('/').get(function(req, res) {
Todo.find(function(err, todos) {
if (err) {
console.log(err);
} else {
res.json(todos);
}
});
});
todoRoutes.route('/:id').get(function(req, res) {
let id = req.params.id;
Todo.findById(id, function(err, todo) {
res.json(todo);
});
});
todoRoutes.route('/update/:id').post(function(req, res) {
Todo.findById(req.params.id, function(err, todo) {
if (!todo)
res.status(404).send("data is not found");
else
todo.todo_description = req.body.todo_description;
todo.todo_responsible = req.body.todo_responsible;
todo.todo_priority = req.body.todo_priority;
todo.todo_completed = req.body.todo_completed;
todo.save().then(todo => {
res.json('Todo updated!');
})
.catch(err => {
res.status(400).send("Update not possible");
});
});
});
todoRoutes.route('/add').post(function(req, res) {
let todo = new Todo(req.body);
todo.save()
.then(todo => {
res.status(200).json({'todo': 'todo added successfully'});
})
.catch(err => {
res.status(400).send('adding new todo failed');
});
});
app.use('/todos', todoRoutes);
app.listen(PORT, function() {
console.log("Server is running on Port: " + PORT);
});
the post request:
the get request:
To confirm here's the output in mongodb:
the problem is that the body needs to be Json(application/json) instead of Text
Everything is fine with your code
Just add this line to your todo.model.js
module.exports = mongoose.model('Todo', Todo);
1:
Edit:
I also had this problem and I fixed Content-type: application / json and it worked
make sure you added app.use(express.json()) to your server.js file.
Try using body-parser and use:
app.use(bodyParser.json());
In the app.js file

Resources