Mongoose RESTful api object.id ref - javascript

i try to build RESTful api for todos application.
Todos Scheme:
const mongoose = require('mongoose');
const TodosScheme = new mongoose.Schema({
id: String
});
module.exports = mongoose.model('Todos', TodosScheme);
Task Scheme:
const mongoose = require('mongoose');
const TaskScheme = new mongoose.Schema({
id: String,
todosID: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Todos'
},
content: String,
isDone: Boolean
});
module.exports = mongoose.model('Task', TaskScheme);
so if user create task it will be reference for some Todos item.
i start to write route for create todos list
app.post('/api/todos/create', (req, res) => {
newTodos = new Todos({});
newTodos.save((err, todos) => {
if (err) res.status(400).json(err);
res.json(todos);
});
});
and now i try to write route to create task
app.post('/api/todos/create/task', (req, res) => {
const body = req.body;
console.log(body);
let newTask = new Task({
todosID: body.todosID, //here i not sure!
content: body.content || 'no content',
isDone: body.isDone || false
});
newTask.save((err, task) => {
if (err) res.status(400).json(err);
res.json(task);
});
});
so my questions is:
1) to create task i need to pass three params:
content: client will pass from request
isDone: client will pass from request
todosID: X ? client? it's the best way?
2) if client need to pass todosID, this is must be required on Task scheme?
because if user create task now without todosID he will create task without reference.
3) have a better way to write scheme todos app?
thank for all :)

/api/todos/create returns created todos object. It should contain _id property. To create task, you should send todos._id with content in request body.

Related

Using Mongo/Mongoose, why is an entirely new database created when adding a document to an existing collection?

https://i.imgur.com/w5quRwA.jpg
I manually created a database called "shoppingitems" on the mongodb website console. I then created a model called "products" in an Express app and connected to the database. A collection called "products" was added to the "shoppingitems" database like I expected.
I then went to add a document to the "shoppingitems.products" collection, but instead an entirely new database called "test" was created, with a products collection and my submitted document in that 'test.products" collection instead of the "shoppingitems.products" collection like I intended.
Is there something wrong with my code? I make no mention of a "test" database anywhere, so IDK why it was created in the first place.
index.js
//Express
var express = require("express");
const app = express();
app.use(express.json());
//Mongoose
const dotenv = require("dotenv");
dotenv.config();
const mongoose = require("mongoose");
mongoose
.connect(process.env.MONGO_URL, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() => console.log("db connection succesfull"))
.catch((err) => console.log(err));
//CORS
const cors = require("cors");
app.use(cors());
//Routes
const productRoute = require("./routes/products");
app.use("/", productRoute);
//RUN INDEX.JS
app.listen(5000, () => {
console.log("backend server is running");
});
routes/products.js
var express = require("express");
var router = express.Router();
var Product = require("../models/Products");
/* GET PRODUCTS FOR HOMEPAGE */
router.get("/", async (req, res) => {
try {
productList = await Product.find();
res.json(productList);
} catch (error) {
console.log(error);
}
});
//POST PRODUCTS TO DATABASE
router.post("/", async (request, response) => {
console.log("request.body= ", request.body);
const newProduct = new Product(request.body);
try {
const savedProduct = await newProduct.save();
response.status(201).json(savedProduct);
} catch (err) {
response.status(500).json(err);
}
});
module.exports = router;
models/Products.js
const mongoose = require("mongoose");
const ProductSchema = new mongoose.Schema({
name: { type: String },
price: { type: Number },
description: { type: String },
image: { type: String },
stripeId: { type: String },
});
module.exports = mongoose.model("Product", ProductSchema);
Am I missing something? I don't see anything in the code that would be causing this and creating a "test" database. I've only used Mongo once or twice before though so I'm not exactly an expert. Can anybody here see what I'm doing wrong?
I'll post any additional code or information that you think is necessary to solving this. Just tell me what else you need to see.
test is the default database name used if you don't specify one. I also notice that nowhere in the code is a shoppingsitems database mentioned.
The connection string could contain the database name, but in this code that is taken from an environment variable.

Express/mongoose returns empty array when trying to get request

I am trying to get the list of books from the database. I inserted the data on mongoose compass. I only get an empty array back.
//Model File
import mongoose from "mongoose";
const bookSchema = mongoose.Schema({
title: {
type: String,
required: true,
},
description: {
type: String,
required: true,
},
releasedDate: {
type: String,
required: true,
},
});
const Book = mongoose.model("Book", bookSchema);
export default Book;
//Routes file
import express from "express";
import Book from "./bookModel.js";
const router = express.Router();
router.get("/", async (req, res) => {
const books = await Book.find({});
res.status(200).json(books);
});
make sure you have books data in db.if it is there then try to add then and catch blocks to your code. Then you will get to know what is the error.
await Book.find({})
.then((data) =>{
res.send(data)
})
.catch((err) =>{
res.send(err)
})
When you create your model, change mongoose.model by new Schema and declare _id attribute like:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
const Book = new Schema({
_id: { type: Schema.ObjectId, auto: true },
// other attributes
})
Update: If it doesn't seem to work, try changing _id with other names such as bookID or id, that can be the error, read https://github.com/Automattic/mongoose/issues/1285

NodeJS + MongoDB _message: 'book validation failed'

I just start learning NodeJS and MongoDB. Now ı am working on a small project to learn basic stuff. But ı am getting a error, in this project ı try to insert data to mongodb which is,
userid like;
"5ed6bfe86034a81dbc7226aa" created from random numbers and letters.
But ı can not insert id to mongodb ı got an error. Here is my codes.
Firstly here is my model which is "Book.js"
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const BookSchema = new Schema({
title: {
type: String,
required: true,
},
userid: Schema.Types.ObjectId, //ı defined here no problem.
published: {
type: Boolean,
default: false
},
So, in routes folder my "book.js" like this;
var express = require('express');
var router = express.Router();
//Models
const Book = require('../models/Book');
const User = require('../models/Users');
/* GET book page. */
router.post('/new', function(req, res, next) {
const book = new Book({
title: 'Node JS',
userid: BigInt, //ı got error here.
//what ı should write?
meta: {
votes: 12,
favs: 90
},
category: "History"
});
book.save((err, data) => {
if (err)
console.log(err);
res.json(data);
});
});
so when ı run my server and try to post data to mongodb with using postman ı got an error.
Like this; _message: 'book validation failed',
and more information: Error: book validation failed: userid: Cast to ObjectId failed for value "[Function: BigInt]" at path "userid"
Now, how can ı define "userid" variable? why ı got an error? what ı should write to define userid for mongodb to post data successfully? Thanks in advance.
I think you need to store the _id created in user schema
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const BookSchema = new Schema({
title: {
type: String,
required: true,
},
userid: {
type:Schema.Types.ObjectId,
ref:User,
required:true
},
published: {
type: Boolean,
default: false
},
Then you need to fetch the user id and then store it to Book collection. By specifying ref keyword you can use populate method provided by mongoose to fetch the user info using book schema.
Example program to fetch and save _id
exports.postaddFoods=(req,res,next)=>{
const foodname=req.body.foodname;
const image=req.body.image;
const shopname=req.shop.shopName;
const price=req.body.price;
Shop.findOne({shopName:shopname})
.then(sid=>{
const food= new Food({
foodName:foodname,
image:image,
shopName:shopname,
price:price,
shopId:sid._id
});
return food.save()
})
This is not a solution
#Dharani Shankar , here is my routes/book.js
router.post('/new', (req,res,next) => {
Book.findOne({title: "NodeJS"})
.then(sid => {
const book = new Book({
title: "Node JS",
meta: {
votes: 12,
favs: 90
},
category: "History",
userid: sid._id
});
book.save((err, data) => {
if (err)
console.log(err);
res.json(data);
});
});
});
sorry for late reply. Note: I have to post my data from that url "localhost:3000/books/new" ı am using postman for testing.

is this code true to query all documents in mongodb via mongoose?

i'm using MongooseJS and doesn't return anything in console or res.json
is it about find function ?
const router = require("express").Router();
var Panel = require("../models/Panel");
router.get("/panels", (req, res) => {
Panel.find({}, function(err, panels) {
if (err) res.send(err);
console.log(panels);
res.json(panels);
});
});
This is the mongoose model for Panel section
const mongoose = require("mongoose");
const Panel = mongoose.model(
"Panel",
new mongoose.Schema({
name: String,
const: Number,
salons: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Salon"
}
]
})
);
module.exports = Panel;
Problem solved, by catching errors, and trying to use anyone can access database, it was about my proxy :)

Using findOne and findOneAndUpdate with HTTP request (mongoose)

I am making an api rest in which I want to make HTTP requests using Postman, specifically I want to perform a search or update a mongodb document, but this must be by an id which is not the doc_id that provides mongo
models Schema
'use strict'
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const infoClientSchema = Schema ({
idusr: String, /*this is require*/
name: String,
phone: Number,
address: String,
riff: String,
state: String,
city: String,
email: {type: String}
})
module.exports = mongoose.model('InfoCli',infoClientSchema)
Controller (This is the get method I know using findById and is working)
'use strict'
const InfoCli = require('../models/infoclient')
function getInfoCli(req, res){
let infocliId = req.params.infocliId
InfoCli.findById(infocliId, (err, infocli) =>{
if (err) return res.status(500).send({message: 'Error making
request: $(err)'})
if (!infocli) return res.status(404).send({message: 'The client does
not exist '})
res.status(200).send({infoclient: infocli})
})
}
Controller (This is the get method which I thought would work using findOne)
function getInfoByUsr(req, res){
let idusr = req.body.idusr
InfoCli.findOne(idusr, (err, infocli) => {
if (err) return res.status(500).send({message: 'Error making
request: $(err)'})
if (!infocli) return res.status(404).send({message: 'The client does
not exist '})
res.status(200).send({infoclient: infocli})
console.log(infocli) /*The console is not showing anything*/
})
}
Controller (This is the put method which I thought would work using findOneAndUpdate)
function updateByUsr(req, res){
let idusr = req.body.idusr
let update = req.body
InfoCli.findOneAndUpdate(idusr, update, (err, infocliUpdate) => {
if (err) return res.status(500).send({message: 'Error making
request: $(err)'})
if (!idusr) return res.status(404).send({message: 'The client does
not exist '})
res.status(200).send({infocliente: infocliUpdate})
})
}
Routes (not 100% sure about this)
const express = require('express')
const InfoCliCtrl = require('../controllers/infoclient')
const api = express.Router()
api.get('/infoclient/:infocliId', InfoCliCtrl.getInfoCli) /*working*/
api.get('/infoclient/:idusr', InfoCliCtrl.getInfoByUsr)
In your app.js/server.js
you should have bodyparser installed
api.get('/infoclient/:infocliId', InfoCliCtrl.getInfoCli)
api.post('/infoclient/:idusr', InfoCliCtrl.updateByUsr)
If you are passing data as URL parameter, like this /infoclient/:infocliId then you can access that using req.params.infocliId
If you are passing using POST body then you can access data using req.body.
In infoClient.js
To fetch user data
exports.getInfoCli = function(req, res, next){
var incomingData = req.params.infocliId;
InfoCli.findOne({idusr: incomingData}, function(err, data){
if(err){
return res.status(500);
} else {
return res.status(200).send({infoclient: data})
}
});
}
Call the above code by
GET - http://localhost:port/infoclient/3874234634 this 3874234634 is your infocliId you need to pass in route
To update user data
exports.updateByUsr = function(req, res, next){
var userId = req.params.idusr;
var updateData = req.body;
InfoCli.findOneAndUpdate({idusr: userId}, updateData, {new: true }, function(err, data){
if(err){
return res.status(500);
} else {
return res.status(200).send(data)
}
});
}
In the update code we have used {new : true} is to return updated document from DB
Call the above code by
POST method - http://localhost:port/infoclient/3874234634 with data in POST body {name: 'pikachu', phone: 12345, ...}
so you read the userid in url parameter using req.params and body data in req.body
I think you simply need to change the line let idusr = req.body.idusr in your getInfoByUsr() function to let idusr = req.params.idusr
http://expressjs.com/en/api.html#req.body
http://expressjs.com/en/api.html#req.params
Also check the syntax of your findOne and findOneAndUpdate query (because idusr is not a Mongo _id but sort of custom String id):
InfoCli.findOne({ idusr: idusr }, (err, infocli) => { ...
InfoCli.findOneAndUpdate({ idusr: idusr }, update, (err, infocliUpdate) => {..
http://mongoosejs.com/docs/api.html#model_Model.findOne
Thank you all, your answers help me to correct many things in the code.
The problem was a horrible mistake in the routes
See how I was using the same path for two requests
api.get('/infoclient/:infocliId', InfoCliCtrl.getInfoCli) /*working*/
api.get('/infoclient/:idusr', InfoCliCtrl.getInfoByUsr)
The problem was that when I used the identifier for idusr it was in conflict with the ObjectId search
Now
api.get('/infoclient/idusr/:idusr', InfoCliCtrl.getInfoByUsr)

Categories

Resources