Node Rest API issue with controller - node.js

I developed my node rest api as usual but this time it is showing some invalid error in controller.js file. The mongoose is not getting required. When I hit the API in postman, it gives the error as :
{
"error": {
"message": "Tweets is not a constructor"
}
}
I even updated my packages for the same, but nothing seems to work. Here is the snippet of my controller for tweets.js:
const mongoose = require('mongoose');
const Tweets = require('../models/tweets');
exports.get_all_tweets = (req, res, next) => {
Tweets.find()
.exec()
.then(docs => {
console.log(docs);
res.status(200).json(docs);
})
.catch(err => {
console.log(err);
res.status(500).json({
error: err
});
});
}
exports.create_tweets = (req, res, next) => {
const tweetbody = req.body;
tweetbody._id = mongoose.Types.ObjectId();
const tweet = new Tweets(tweetbody);
tweet
.save()
.then(docs => {
console.log(docs, 'Tweets');
res.status(200).json(docs);
})
.catch(err => {
console.log(err, 'error found');
res.status(500).json({
error:err
});
});
The first mongoose line is appearing blank as shown in the screenshot:
mongoose
Model for tweets.js:
const mongoose = require('mongoose');
const tweetSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
time: { type: String},
count: { type: Number}
});
module.export = mongoose.model('Tweets', tweetSchema);

please check all path and add new keyword before schema initializing
Model for tweets.js:
const tweetSchema = new mongoose.Schema({

Try this using async/await
exports.get_all_tweets = async (req, res, next) => {
const result = await Tweets.find()
res.status(200).json(result);
}

module.exports with a 's' at the end :)

Related

How to delete a doc with id with mongoose?

I want to delete a doc with id in mongoose. It executes the method but doesn't delete that doc in MongoDB Altas.
Note:Everthing is correct and also Passing id correctly in PostMan.
here is my controller :
const Post = require("../models/Post");
const mongoose = require("mongoose");
exports.postPost = async (req, res) => {
try {
const post = await new Post({
_id: new mongoose.Types.ObjectId(),
title: req.body.title,
desc: req.body.desc,
}).save();
console.log("Saved in db!");
return res.status(201).json({
success: true,
data: post,
});
} catch (error) {
return res.status(500).json({
success: false,
message: "Server Error",
});
}
};
exports.deletePost = async (req, res) => {
let postID = req.params.id;
await Post.deleteOne({ _id: postID }, (err, data) => {
if (err) {
res.status(500).json({
message: "Something went wrong, please try again later.",
});
} else {
res.status(200).json({
message: "Post Deleted",
data: data,
});
}
});
};
here is my posts route:
const express = require("express");
const router = express.Router();
const {
postPost,
deletePost,
} = require("../controllers/posts_controller");
router.route("/:id").delete(deletePost);
router.route("/").post(postPost);
module.exports = router;
here is my postman :
here is my mongodb altas:
use the findOneAndDelete({_id:postId}) instead of deleteOne in posts controller
Or
use findByIdAndDelete(postId) instead of deleteOne in posts controller
exports.deletePost = async (req, res) => {
let postID = req.params.id;
await Post.findByIdAndDelete(postID, (err, data) => {
if (err) {
res.status(500).json({
message: "Something went wrong, please try again later.",
});
} else {
res.status(200).json({
message: "Post Deleted",
data: data,
});
}
});
};

Node + Express: How to retrieve data from MongoDB via Azure

I am a frontend developer. A colleague has kindly built me a MongoDB/Cosmos database in Azure and allowed me to retrieve a single record into my frontend. He has since gone on holiday with no cover.
(I am confused what type of database it is, since it says Azure Cosmos DB in Azure portal, but all the code in my server.js file refers to a MongoDB.) Server.js:
const express = require('express');
const app = express();
const url = 'mongodb://blah.azure.com';
app.use(express.static('static'));
const mongoClient = require('mongodb').MongoClient
let db;
app.listen(process.env.PORT || 3000, async () => {
console.log('App listening on port 3000!')
const connect = await mongoClient.connect(url)
db = connect.db('ideas');
});
app.get('/api/ideas/:name', async (req, res) => {
return res.json(await db.collection('container1').findOne({key: req.params.name}));
});
I want to retrieve all documents in this database. They each have an ID. But my colleague seems to have defined an API by name. From the MongoDB docs I can use the command find({}) instead of findOne({key: req.params.name}) to return all records, but this does not work (i.e. I get no output to the console). I presume this is because of the '/api/ideas/:name'.
I have also tried:
db.open(function(err, db){
var collection = db.collection("container1");
collection.find().toArray(function(err2, docs){
console.log('retrieved:');
console.log(docs);
})
})
but i get an error that tells me I can't retrieve the property "open" of undefined.
Can anyone help me either: (1) work out how to change the API in Azure, or (2) rewrite this code to retrieve all records? I will also need to edit and insert records. Thanks
If you want to retrive data from Mongo DB in nodejs espresso application, I suggest you use the package mongoose.
For example
Create mongo.js file to add connection details
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
const accountName= 'testmongo05',
const databaseName= 'test',
const key= encodeURIComponent(''),
const port: 10255
const mongoUri = `mongodb://${env.accountName}:${key}#${accountName}.documents.azure.com:${port}/${databaseName}?ssl=true`;
function connect() {
mongoose.set('debug', true);
return mongoose.connect(mongoUri, {
useFindAndModify : false,
useCreateIndex: true,
useNewUrlParser: true,
useUnifiedTopology: true
});
}
module.exports = {
connect,
mongoose
};
Define models
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const userSchema = new Schema(
{
userId: {
type: String,
required: true,
unique: true
},
name: String,
saying: String
},
{
collection: 'Users'
}
);
const User = mongoose.model('User', userSchema);
module.exports = User;
CURD operations
const express = require('express');
const bodyParser = require('body-parser');
const User = require('./module/user');
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
require('./mongo').connect().catch(error => console.log(error));
//list users
app.get('api/users', async (req, res) => {
const docquery = User.find({});
await docquery
.exec()
.then(users => {
res.status(200).json(users);
})
.catch(error => {
res.status(500).send(error);
});
});
// get user by userId
app.get('/api/user/:uid', async (req, res) => {
const docquery =User.findOne({userId:req.params.uid })
await docquery
.exec()
.then(user => {
if (!checkFound(res, user)) return;
res.status(200).json(user);
})
.catch(error => {
res.status(500).send(error);
});
});
// create
app.post('/api/user', async (req, res) => {
const originalUser= { userId: req.body.userId, name: req.body.name, saying: req.body.saying };
const user = new User(originalUser);
await user.save(error => {
if (checkServerError(res, error)) return;
res.status(201).json('User created successfully!');
console.log('User created successfully!');
});
});
//update user by userId
app.put('/api/user/:uid', async (req, res) => {
const docquery =User.findOneAndUpdate({userId: req.params.uid}, req.body)
await docquery.exec()
.then((user) =>{
if (!checkFound(res, user)) return;
res.status(200).json("User update successfully");
console.log('User update successfully!');
})
.catch(error =>{
res.status(500).send(error);
})
});
//delete user by userId
app.delete('/api/user/:uid', async (req, res) => {
const docquery = User.findOneAndRemove({userId: req.params.uid })
await docquery.exec()
.then(user =>{
if (!checkFound(res, user)) return;
res.status(200).json("user deleted successfully!");
console.log('user deleted successfully!');
})
.catch(error =>{
res.status(500).send(error);
})
});
function checkServerError(res, error) {
if (error) {
res.status(500).send(error);
return error;
}
}
function checkFound(res, user) {
if (!user) {
res.status(404).send('user not found.');
return;
}
return user;
}
Test
a. Create user
b. get user
c. List Users
d. Update User
e delete user

array of objects won't POST into mongodb

I have an array of objects that is defined in mongoose schema as
blacklistGroup: {
userId: { type: String },
username: { type: String }
}
I can't figure out why it won't POST into mongodb.
I have a console.log that shows that it represents it's schema, but it never appears in mongodb? What am I doing wrong?
console.output
req.body.blacklistGroup
[ { userId: '5e2350c7f88cfb331c4f67de', username: 'artist1' },
{ userId: '5e20c5a139a92512cc7df63c', username: 'artist' } ]
[object Object]
app.js
app.post("/api/listings", checkAuth, (req, res, next) => {
console.log("req.body.blacklistGroup");
console.log(req.body.blacklistGroup);
let blacklistGroup = req.body.blacklistGroup;
console.log("req.body.blacklistGroup");
const post = new Post({
blacklistGroup: req.body.blacklistGroup,
});
//saves to database with mongoose
post.save().then(result => {
console.log(result);
res.status(201).json({
message: "Auction listing created successfully!",
postId: result._id
});
});
});
You can store all user at once. use mongoose insertMany
const Post = require('post'); //mongoose schema
app.post("/api/listings", checkAuth,(req, res, next) => {
console.log("req.body.blacklistGroup");
console.log(req.body.blacklistGroup);
let blacklistGroup = req.body.blacklistGroup;
console.log("req.body.blacklistGroup");
const blacklistGroup = req.body.blacklistGroup;
(async function(){
await Post.insertMany(blacklistGroup);
res.status(200).send('Ok');
})();
});
Or you can use
const Post = require('post'); //mongoose schema
app.post("/api/listings", checkAuth,async (req, res, next) => {
console.log("req.body.blacklistGroup");
console.log(req.body.blacklistGroup);
let blacklistGroup = req.body.blacklistGroup;
console.log("req.body.blacklistGroup");
const blacklistGroup = req.body.blacklistGroup;
await Post.insertMany(blacklistGroup);
res.status(200).send('Ok');
});
For More Here
You don't have an array of objects (or at least you don't want one), you have an object with two properties; userId and username. MongoDB is expecting JSON and it looks like you're trying to send it an array containing that object.
Try this:
let blacklistGroup = req.body.blacklistGroup[0];
To process an array of objects passed as req.body.blacklistGroup, you will have to iterate over it, define a new Post for each object and then send it. I think part of the confusion here is that your Schema is called blacklistGroup but it doesn't refer to a group, it refers to one entry.
const dbCalls = blacklistGroup.map(userObject => {
const post = new Post({
blacklistGroup: {
userId: userObject.userId,
username: userObject.username
});
return new Promise((resolve, reject) => {
post.save.then(() => {
resolve();
})
.catch(err => {
reject(err);
})
})
});
Promise.all(dbCalls).then(() => {
res.status(201).json({message: "Auction listings created successfully!"})
})
.catch(err => {
res.status(500).json({error: err})
});

Resolving UnhandledPromiseRejectionWarning in express post request

I am trying to make a post request to the server (mongodb) but I get this error:
UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'todo_description' of undefined
I am running mongodb on my localhost
// Require Express
const express = require("express");
// Setting Express Routes
const router = express.Router();
// Set Up Models
const Todo = require("../models/todo");
// Get All Todos
router.get("/", async (req, res) => {
try {
const todo = await Todo.find();
res.json(todo);
} catch (err) {
res.json({ message: err });
}
});
router.get("/:id", async (req, res) => {
try {
const id = req.params.id;
await Todo.findById(id, (err, todo) => {
res.json(todo);
});
} catch (err) {
res.json({ message: err });
}
});
router.post("/add", async (req, res) => {
const todo = new Todo({
todo_description: req.body.todo_description,
todo_responsible: req.body.todo_responsible,
todo_priority: req.body.todo_priority,
todo_completed: req.body.todo_completed,
});
try {
await todo.save();
res.json(todo);
} catch (err) {
res.json({ message: err });
}
});
router.patch("/update/:id", async (req, res) => {
try {
const updateTodo = await Todo.updateOne(
{ _id: req.params.id },
{ $set: { todo_description: req.body.todo_description } }
);
updateTodo.save().then(updateTodo => {
res.json(updateTodo);
});
} catch (err) {
res.json({ message: err });
}
});
router.delete("/delete/:id", async (req, res) => {
try {
const deleteTodo = await Todo.deleteOne({ _id: req.params.id });
res.json(deleteTodo);
} catch (err) {
res.json({ message: err });
}
});
module.exports = router;
my todo model
// Require Mongoose
const mongoose = require("mongoose");
// Define Schema
// const Schema = new mongoose.Schema;
// Define Todo-Schema
const TodoSchema = new mongoose.Schema({
// Creating Fields
todo_description: {
type: String
},
todo_responsible: {
type: String
},
todo_priority: {
type: String
},
todo_completed: {
type: Boolean
},
todo_date: {
type: Date,
default: Date.now
}
});
// Compile Model From Schema
// const TodoModel = mongoose.model("Todos", TodoSchema);
// Export Model
module.exports = mongoose.model("todos", TodoSchema);
error message:
(node:548) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'todo_description' of undefined
at router.post (C:\Users\kinG\Desktop\projects\mountain-of-prototype\mern\backend\routes\todo.js:33:32)
at Layer.handle [as handle_request] (C:\Users\kinG\Desktop\projects\mountain-of-prototype\mern\backend\node_modules\express\lib\router\layer.js:95:5)
thank you
You are accessing todo_description from req.body. req.body will only be available if you add the body-parser middleware or add a similar one yourself.
Add this right before your routes are loaded :
const bodyParser = require('body-parser');
const express = require('express');
const app = express();
app.use(bodyParser.json());
You can also add this to a specific route. Read more about it here.
You should use body-parser in your master file of the application. Which gives you the parsed json before your middle-ware parse the body, which by-default in string. And also make sure you are sending todo_description in the req.body(should check before use).
const bodyParser = require('body-parser');
app.use(bodyParser.json());

Error running mongoose update code ( router.patch() )

I'm getting an error running router.patch() code to update a product on a cloud-based mongoose database. I'm using Postman to simulate the update. Postman's error is showing, "req.body[Symbol.iterator] is not a function." Here is the relevant code:
Products.js:
const express = require('express');
const router = express.Router();
const mongoose = require('mongoose');
const Product = require('../models/product');
router.patch('/:productId', (req, res, next) => {
const id = req.params.productId;
// don't want to update both fields if not needed
const updateOps = {};
// loop through all the operations of the request body
for (const ops of req.body) {
updateOps[ops.propName] = ops.value;
}
Product.update({_id: id}, { $set: updateOps })// $set is a mongoose object
.exec()
.then(result => {
console.log(result);
res.status(200).json(result);
})
.catch(err => {
console.log(err);
res.status(500).json({
error: err
});
});
{req.body.newName, price, req.body.newPrice} ;
res.status(200).json({
message: 'Updated product',
});
});
module.exports = router
Product.js:
const mongoose = require('mongoose');
const productSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
name: String,
price: Number
});
// export the schema into the Mongoose model
module.exports = mongoose.model('Product', productSchema);
Any help would be greatly appreciated. :-)
As I commented, this part is likely your problem:
for (const ops of req.body) {
updateOps[ops.propName] = ops.value;
}
Since req.body is an Object, I think you want:
for (let [key, value] of Object.entries(req.body)){
updateOps[key.propName] = value;
}
Or something similar.

Resources