Newbie in Node js, I am using Node JS to build APIs and using class. There are 2 routes till now, one is to fetch all users which is working fine, another is to insert new user which is not working. It is returning {} with status 500.
Here are the files.
index.js
import server from "./config/server.js";
import './config/database.js';
const PORT = process.env.PORT || 5000;
server.listen(PORT, () => {
console.log(`app running on port ${PORT}`);
});
config/database.js
import mongoose from "mongoose";
class Connection {
constructor() {
const url =
process.env.MONGODB_URI || `mongodb://localhost:27017/dev-muscles`;
console.log("Establish new connection with url", url);
mongoose.Promise = global.Promise;
// mongoose.set("useNewUrlParser", true);
// mongoose.set("useFindAndModify", false);
// mongoose.set("useCreateIndex", true);
// mongoose.set("useUnifiedTopology", true);
mongoose.connect(url);
}
}
export default new Connection();
config/server.js
import express from "express";
import UserController from "../src/models/controllers/UserController.js";
const server = express();
server.use(express.json());
server.get(`/users`, UserController.getAll);
server.post(`/users/create`, UserController.create);
export default server;
src/models/User.js
import mongoose from "mongoose";
const { Schema } = mongoose;
import validator from "validator";
class User {
initSchema() {
const schema = new Schema({
first_name: {
type: String,
required: true,
trim: true
},
last_name: {
type: String,
required: true,
trim: true
},
email: {
type: String,
required: true,
trim: true,
lowercase: true,
// validate(value) {
// if( !validator.isEmail(value) ) {
// throw new Error('Email is invalid')
// }
// }
},
phone: {
type: Number,
required: true,
trim: true
},
password: {
type: String,
required: true
}
});
// schema.plugin(validator);
mongoose.model("users", schema);
}
getInstance() {
this.initSchema();
return mongoose.model("users");
}
}
export default User;
src/controllers/UserController.js
import Controller from "./Controller.js";
import User from ".././models/User.js";
const userModelInstance = new User().getInstance();
class UserController extends Controller {
constructor(model) {
super(model);
}
}
export default new UserController(userModelInstance);
src/controllers/Controller.js
class Controller {
constructor(model) {
this.model = model;
this.getAll = this.getAll.bind(this);
this.create = this.create.bind(this);
}
async getAll(req, res) { // works fine
return res.status(200).send(await this.model.find({}));
}
async create(req, res) { // this is returning {} with status code 500
try {
// return res.send(req.body);
return res.status(201).send(await new this.model.save(req.body));
} catch (error) {
res.status(500).send(error);
}
}
}
export default Controller;
Refactor the create method like so.
const ItemToSave = new this.model(req.body);
const savedItem = await ItemToSave.save();
return res.status(201).send(savedItem);
Related
Following a youtube tutorial but getting a Validation error i.e ValidationError: Todo validation failed: title: Path title is required.
user_model.ts
import mongoose from "mongoose";
interface Todo_I {
title: string;
description: string;
}
interface TodoDocument extends mongoose.Document {
title: string;
description: string;
}
const todoSchema = new mongoose.Schema({
title: {
type: String,
required: true,
},
description: {
type: String,
required: true,
},
});
interface todoModelInteface extends mongoose.Model<TodoDocument> {
set(x: Todo_I): TodoDocument;
}
todoSchema.statics.set = (x: Todo_I) => {
return new Todo();
}
const Todo = mongoose.model<TodoDocument, todoModelInteface>(
"Todo",
todoSchema,
)
Todo.set({
title: "Some Title",
description: "Some Description"
});
export { Todo };
routes.ts
import express, { Request, Response } from "express"
import { Todo } from "../models/user_model";
const router = express.Router()
router.post('/add', async (req: Request, res: Response) => {
const { title, description } = req.body;
const dataItem = Todo.set({ title, description });
await dataItem.save();
return res.status(200).json({
data: dataItem,
})
});
export { router };
app.ts
import express, { Request, Response } from "express"
import { router } from "./routes/routes";
import dotenv from "dotenv"
const { mongoose } = require("mongoose");
dotenv.config();
const app = express();
app.use(express.urlencoded({
extended: false
}));
app.use(express.json());
mongoose.connect(
process.env.MONGODB_URL as string,
{
useUnifiedTopology: true,
useNewUrlParser: true,
},
()=>{
console.log("Db Connected!!!")
}
)
app.use("/", router)
app.listen(8080, () => {
console.log("Sever is rocking at 8080");
})
Data which I am posting using PostMan
{
"title": "Some Title",
"description": "Some Description"
}
Error Screenshot
I am creating a MERN stack based website, and was able to write GET and POST requests for two out of the three models I have created so far: users and profile. The latest one, tests, is giving an error of Cannot POST /api/tests. Here's the code:
server.js
const connectDB = require('./config/db');
const app = express();
//Connecting DB
connectDB()
app.use(express.json({extended: false}));
app.get('/',(req,res)=>res.send('API Running'));
app.use('/api/users',require('./routes/api/users'));
app.use('/api/auth',require('./routes/api/auth'));
app.use('/api/profile',require('./routes/api/profile'));
app.use('/api/tests', require('./routes/api/tests'));
const PORT = process.env.Port || 5000;
app.listen(PORT, ()=> console.log(`Server started on port on ${PORT}`));
Test.js
const TestSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
domain: {
type: String,
required: true
},
activeStatus: {
type: Boolean,
required: true
},
questions: [
{
question: {
type: String,
required: true
},
option1: {
type: String,
required: true
},
option2: {
type: String,
required: true
},
option3: {
type: String,
required: true
},
option4: {
type: String,
required: true
},
answer: {
type: Number,
required: false
}
}
]
});
module.exports = Test = mongoose.model('test', TestSchema);
tests.js
const router = express.Router();
const { check, validateResult } = require('express-validator/check');
const auth = require('../../middleware/Auth');
const Test = require('../../models/Test');
const User = require('../../models/User');
// #route POST api/tests
// #desc Create or Update a test
// #access Private
router.post('/', [
check('name', 'Name is required').not().isEmpty(),
check('domain', 'Domain is required').not().isEmpty(),
check('status', 'Status is required').not().isEmpty()
],
async (req, res) => {
console.log("entered");
const errors = validationResult(req);
if(!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const {
name,
domain,
status
} = req.body;
//build test object
const testFields = {};
if(name) testFields.name = name;
if(domain) {console.log(123); testFields.domain = domain;}
if(status) testFields.status = status;
testFields.questions = {};
try {
//see if test exists
// let test = await Test.findOne({name});
// if(test){
// return res.status(400).json({ errors: [{msg: "Test already exists"}] });
// }
//create
test = new Test(testFields);
await test.save();
res.json(test);
console.log(testFields);
res.send('Test Created')
} catch (err) {
console.error(err.message);
res.status(500).send('Server Error');
}
});
// #route GET api/tests
// #desc Get particular test
// #access Private
router.get('/', auth, async (req, res) => {
try {
const test = await Profile.findById(req.test.id);
console.log(test);
if(!test)
return res.status(400).json({ msg: 'Test not found' });
res.json(test);
} catch (err) {
console.error(err.message);
res.status(500).send('Server Error');
}
});
module.exports = router;
Things I've already tried:
Checked and rechecked the URL entered in Postman (http://localhost:5000/api/tests)
Set the URL type in Postman to POST
Made sure the URL was properly registered, and compared with working URLs and files
Even after this, nothing has worked so far. I am fairly new to this, so that might be the cause of my oversight, please do let me know if you can spot where it's going wrong.
I am trying to integrate mongoose and apollo with Next.js
I wrote this wrapper around apollo server:
import mongoose from "mongoose"
const {logger} = require("../middleware/logger");
const connect = async () => {
logger.info("Connecting to DB...");
await mongoose
.connect(process.env.MONGO_URI, {
useNewUrlParser: true,
useFindAndModify: false,
useUnifiedTopology: true
}).then(() => logger.info(`Mongo running at ${process.env.MONGO_URI}`))
.catch(err => logger.error(err));
}
const connectDB = (handler) => async (req, res) => {
if (mongoose.connections[0].readyState !== 1) {
await connect();
}
return handler(req, res);
}
const db = mongoose.connection;
db.once('ready', () => logger.info(`Connected to mongo on ${process.env.MONGO_URI}`));
export default connectDB;
In this model in separate file:
const mongoose = require('mongoose');
const {Schema} = mongoose;
const CustomerSchema = new Schema({
name: {
type: String,
required: [true, 'Customer name is required'],
unique: true,
trim: true,
},
createdAt: {
type: Date,
default: Date.now
}
}, {
toJSON: {
transform: function (doc, ret) {
ret._id = ret._id.toString();
delete ret.__v
}
}
});
module.exports = mongoose.model('Customer', CustomerSchema);
My apollo server looks like this now:
import {ApolloServer, gql} from "apollo-server-micro";
import connectDB from "../../middleware/db-middleware";
const _Customer = require("../../db/models/Customer");
const typeDefs = gql`
type Customer {
id: ID!
name: String!
createdAt: String
}
type Query {
hello: String!
}
type NewCustomerResponse {
success: Boolean!
message: String
}
type Mutation {
addCustomer(name: String!): NewCustomerResponse!
}
`;
const resolvers = {
Mutation: {
addCustomer: async (parent, {name}, context, info) => {
await _Customer.create({name});
return {success: true, message: "Sample message"};
}
}
};
const apolloServer = new ApolloServer({
typeDefs,
resolvers,
context: () => ({}),
});
export default connectDB(apolloServer.createHandler({path: "/api/gql"}));
First run works ok, but when I modify anything, and next.js auto-recompiles source files, it throws this error:
OverwriteModelError: Cannot overwrite `Customer` model once compiled.
Does anyone knows what am I doing wrong and how to resolve this issue?
I'm new to NodeJS,I'm just trying to create a restfull API, but when I try to execute the code by running (npm run dev),it's throwing an error.There are many questions like this one, but no answer could figure out what is wrong in my code.
the error is : app.use() requires a middleware function
this is my index.js
const express = require("express");
const app = express()
const departmentRouter = require("../src/routes/department")
app.use(express.json())
app.use(departmentRouter)
const port = process.env.PORT || 3000;//local machine port 3000
app.listen(port, () => (`Server running on local machine port ${port} 🔥`));
this is the model :
const mongoose = require("mongoose");
const validator = require('validator')
const Department = mongoose.model('Department', {
name: {
type: String,
required: true,
}
,
email: {
type: String,
required: true,
trim: true,
lowercase: true,
validate(value) {
if (!validator.isEmail(value)) {
throw new Error('Invalid email!')
}
}
}
,
createdBy: {
type: String,
default: 'SYS_ADMIN'
}
,
updatedBy: {
type: String,
default: 'SYS_ADMIN'
}
,
createdAt: {
type: Date
// ,
// default: Date.getDate()
}
,
updatedAt: {
type: Date
// ,
// default: Date.getDate()
},
isDeleted: {
type: Boolean,
default: false
}
})
module.exports = Department
this is routes file (department.js)
const express = require("express");
const router = express.Router();
const Department = require("../models/department")
router.get("/v1/departments", async (req, res) => {
try {
const departments = await Department.find({ isDeleted: false })
if (!departments) {
return res.status(404).send()
}
res.status(200).send()
} catch (error) {
res.status(500).send(error)
}
});
router.get("/v1/department/:id", async (req, res) => {
//test if the department exist => by id
const _id = req.params._id
try {
const depatment = await Department.findByid(_id, { isDeleted: false })
if (!depatment) {
return res.status(404).send()
}
res.status(200).send(depatment)
} catch (error) {
res.status(500).send(error)
}
});
router.post("/v1/department", async (req, res) => {
try {
const department = new Department(req.body) //this param is for testing the post methode by sending request from postman
await department.save()
} catch (error) {
res.status(500).send(error)
}
});
router.put("/v1/department/:id", async (req, res) => {
//especially useful when testing the put method using postman
const updates = Object.keys(req.body)
const allowedUpdates = ['name', 'email']
const isValideOperations = updates.every((update) => allowedUpdates.includes(update))
if (!isValideOperations) {
return res.status(400).send({ error: 'Invalid updates' })
}
try {
const _id = req.params.id
const department = await Department.findByIdAndUpdate(_id)
if (!department) {
return res.status(404).send()
}
res.send(department)
} catch (error) {
res.status(500).send(error)
}
})
//Safe delete by updating the field isDeleted to true
router.delete('/v1/department/:id', async (req, res) => {
try {
const _id = req.params.id
const department = await Department.findByIdAndUpdate(_id, { isDeleted: true })
if (!department) {
return res.status(400).send()
}
res.status(200).send(department)
} catch (error) {
res.status(500).send(error)
}
})
In the department.js file, you need to export the router:
module.exports = router
I am new in Nodejs. I am using Node.js first time. I am trying to integrate a Nodejs API with React.js application. I don't know why this error is coming. My files are like below.
index.js
import express from 'express';
import path from 'path';
import mongoose from 'mongoose';
import bodyParser from 'body-parser';
import auth from "./routes/auth";
const app = express();
app.use(bodyParser.json());
mongoose.connect('mongodb://127.0.0.1:8080/bookworm', { useNewUrlParser: true });
app.use("/api/auth", auth);
app.get('/*',(req,res)=> {
res.sendFile(path.join(__dirname,'index.html'));
});
app.listen(8080, ()=> console.log("Running on localhost:8080"));
auth.js
import express from 'express';
import User from '../models/User';
const router = express.Router();
router.post("/", (req,res) => {
const { credentials } = req.body;
User.findOne({ email: credentials.email }).then(user => {
if (user) {
} else {
res.status(400).json({errors: { global: "Invalid creadentials"}})
}
});
});
export default router;
User.js
import mongoose from 'mongoose';
const schema = new mongoose.Schema(
{
email: { type: String, required: true, lowercase: true, index: true },
passwordHash: { type: String, required: true }
},
{ timestamps: true }
);
export default mongoose.model('User', schema);
I am getting error like below
What is the solution ?
Try this:
User.findOne({ email: credentials.email })
.then(user => {
if(!user){
res.status(400).send({errors: { global: "Invalid creadentials"}});
} else {
res.status(200).send({user});
}
})
.catch(errors => {
res.status(400).send({errors: { global: errors.message }});
})
According to the error messages, I just added the catch() method to handle the promise rejection.