Mongoose not retrieving data from atlas - express

Can someone help me with this problem, mongoose not fetching any data from MongoDB atlas? Everything is fine and I am able to fetch data from cmd, but with mongoose, it returns an empty array.
const express = require('express');
const cors = require('cors');
const mongoose = require('mongoose');
const app = express()
app.use(express.json())
app.use(express.urlencoded())
app.use(cors())
const dotenv = require('dotenv');
dotenv.config()
mongoose.connect(process.env.DB_ACCESS, () => {
console.log("db connected successfully..")
})
const hospitalTemplate = new mongoose.Schema({
state: {
type: String,
required: true
},
city: {
type: String,
required: true
},
hospitalname: {
type: String,
required: true
},
mobilenumber: {
type: Number,
required: true
},
image1url: {
type: String,
required: true
},
rating: {
type: Number,
required: true
},
availablebeds: {
type: Number,
required: true
}
})
const Hospital = new mongoose.model('Hospital', hospitalTemplate)
// // Routes
app.get("/search", async (req, res)=> {
await Hospital.find({}, (err, data)=> {
if (data) {
res.send(data);
console.log(data)
} else {
res.send({ message: "data problem" });
console.log("data problem");
}
}).clone().catch(function(err){ console.log(err)})
})
app.listen(4000,() => {
console.log("server is running")
})
After running this program, I get an empty array when I visit "localhost:4000/search"

Related

How do I save the state of a page in Express JS?

I'm creating a website that allows users to create a video-board and display YouTube videos, and they can drag/resize these videos. I want users to be able to save their video board page in a unique URL so they can return later, and have multiple different pages.
To do this I've created a unique user id with UUID, and added this to the URL when users create a video board. Then, I connected my website to a MySQL database and used sequelize to create a table using a MVC Pattern. I want to store the state of their video board (positions, videos URL) and assign it to their url. The tables have been created, however, the issue I'm having is nothing is being sent to the database.
GitHub: https://github.com/RyanOliverV/MultiViewer
Controller index:
const controllers = {};
controllers.video = require('./video-board');
module.exports = controllers;
Controller video board:
const { models: { Video } } = require('../models');
module.exports = {
create: (req, res) => {
const { video_url, user_id, position } = req.body;
Video.create({ video_url, user_id, position })
.then(video => res.status(201).json(video))
.catch(error => res.status(400).json({ error }));
},
getAllVideos: (req, res) => {
Video.findAll()
.then(videos => res.status(200).json(videos))
.catch(error => res.status(400).json({ error }));
},
getVideoById: (req, res) => {
const { id } = req.params;
Video.findByPk(id)
.then(video => {
if (!video) {
return res.status(404).json({ error: 'Video not found' });
}
return res.status(200).json(video);
})
.catch(error => res.status(400).json({ error }));
},
update: (req, res) => {
const { id } = req.params;
const { video_url, user_id, position } = req.body;
Video.update({ video_url, user_id, position }, { where: { id } })
.then(() => res.status(200).json({ message: 'Video updated' }))
.catch(error => res.status(400).json({ error }));
},
delete: (req, res) => {
const { id } = req.params;
Video.destroy({ where: { id } })
.then(() => res.status(200).json({ message: 'Video deleted' }))
.catch(error => res.status(400).json({ error }));
},
}
Model index:
const dbConfig = require('../config/db-config');
const Sequelize = require('sequelize');
const sequelize = new Sequelize(dbConfig.DATABASE, dbConfig.USER, dbConfig.PASSWORD, {
host: dbConfig.HOST,
dialect: dbConfig.DIALECT
});
const db = {};
db.sequelize = sequelize;
db.models = {};
db.models.Video = require('./video-board') (sequelize, Sequelize.DataTypes);
module.exports = db;
Model video board:
module.exports = (sequelize, DataTypes) => {
const Video = sequelize.define('video', {
video_url: {
type: DataTypes.STRING,
allowNull: false
},
user_id: {
type: DataTypes.STRING,
allowNull: false
},
position: {
type: DataTypes.JSON,
allowNull: false
}
});
return Video;
}
Route:
const express = require('express');
const router = express.Router();
const { v4: uuidv4 } = require('uuid');
const { video } = require('../../controllers');
router.get('/', (req, res) => {
const user_id = uuidv4();
res.redirect(`/video-board/${user_id}`);
});
router.post('/', (req, res) => {
const { video_url, user_id, position } = req.body;
video.create(req, res, { video_url, user_id, position })
});
router.get('/:id', (req, res) => {
const user_id = req.params.id;
res.render('video-board', { user_id });
});
module.exports = router;
When the user clicks the 'create-video-board' button it creates a unique url, and I'm expecting this to be stored in the database with the page state of that url.

Mongoose schema validation err

i m applying mongoose to my todolist app on node js and to make sure a person doesn't add an empty new item i m using the required field in mongoose schema for new item and it gives no err untill some i checked to see if its working and try adding an empty item it gave me the err message i put into the required field but also crashed the whole app
here's the node js code
//jshint esversion:6
const express = require("express");
const bodyParser = require("body-parser");
const mongoose = require("mongoose")
const app = express();
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static("public"));
mongoose.connect("mongodb://localhost:27017/todolistDB")
const itemsSchema = {
name: String
// {
// type: String,
// required: [true, "naam dal na ba!$^&y"]
// }
}
const Item = mongoose.model("(Item", itemsSchema)
const welcome = new Item({ name: "welcome to list" })
const add = new Item({ name: "+ will add new item" })
const del = new Item({ name: "nuke the mofo" })
const defaultItems = [welcome, add, del]
// Item.insertMany(defaultItems, (err) => {
// if (err) { console.log("err") } else { console.log("success in default") }
// })
app.get("/", function(req, res) {
Item.find({}, (err, foundItems) => {
if (foundItems.length === 0) {
Item.insertMany(defaultItems, (err) => {
if (err) { console.log("err") } else { console.log("success in default") }
})
res.redirect("/")
} else { res.render("list", { listTitle: "today", newListItems: foundItems }); }
})
});
app.post("/", function(req, res) {
const itemName = req.body.newItem;
const newItem = new Item({ name: itemName })
newItem.save()
res.redirect("/")
// if (req.body.list === "Work") {
// workItems.push(item);
// res.redirect("/work");
// } else {
// items.push(item);
// res.redirect("/");
// }
});
app.post("/delete", function(req, res) {
const itemId = req.body.cbox
Item.findByIdAndRemove(itemId, (err) => {
if (!err) {
console.log("deleted item")
res.redirect("/")
} else { console.log("err") }
})
})
app.get("/:userList", (req, res) => {
const nameOFList = req.params.userList
})
app.get("/work", function(req, res) {
res.render("list", { listTitle: "Work List", newListItems: workItems });
});
app.get("/about", function(req, res) {
res.render("about");
});
app.listen(3000, function() {
console.log("Server started on port 3000");
});
this is the error i m getting
Server started on port 3000
C:\Users\zahab\Desktop\todolist-v2-starting-files\node_modules\mongoose\lib\document.js:2980
this.$__.validationError = new ValidationError(this);
^
ValidationError: (Item validation failed: name: naam dal na ba!$^&y
at model.Document.invalidate (C:\Users\zahab\Desktop\todolist-v2-starting-files\node_modules\mongoose\lib\document.js:2980:32)
at C:\Users\zahab\Desktop\todolist-v2-starting-files\node_modules\mongoose\lib\document.js:2769:17
at C:\Users\zahab\Desktop\todolist-v2-starting-files\node_modules\mongoose\lib\schematype.js:1333:9
at processTicksAndRejections (node:internal/process/task_queues:78:11) {
errors: {
name: ValidatorError: naam dal na ba!$^&y
at validate (C:\Users\zahab\Desktop\todolist-v2-starting-files\node_modules\mongoose\lib\schematype.js:1330:13)
at SchemaString.SchemaType.doValidate (C:\Users\zahab\Desktop\todolist-v2-starting-files\node_modules\mongoose\lib\schematype.js:1314:7)
at C:\Users\zahab\Desktop\todolist-v2-starting-files\node_modules\mongoose\lib\document.js:2761:18
at processTicksAndRejections (node:internal/process/task_queues:78:11) {
properties: {
validator: [Function (anonymous)],
message: 'naam dal na ba!$^&y',
type: 'required',
path: 'name',
value: ''
},
kind: 'required',
path: 'name',
value: '',
reason: undefined,
[Symbol(mongoose:validatorError)]: true
}
},
_message: '(Item validation failed'
}
[nodemon] app crashed - waiting for file changes before starting...

Express [Nest.js] - res.cookie() not set in Heroku production

I am using Next.js (Frontend) and Nest.js (Backend) Frameworks and I am having issues with a HTTP Cookies. The following code works in development trough localhost, but not when publishing the code to vercel (Next.js) and Heroku (Nest.js)
Here is a snippet of my Nest.js Setup
// main.ts
async function bootstrap() {
const app = await NestFactory.create(AppModule, {
logger: new LoggerService(),
cors: true,
});
app.use(cookieParser());
app.enableCors({
origin: ["<my-site>"],
credentials: true,
});
...
await app.listen(process.env.PORT || 5000);
}
bootstrap();
Here is my Route:
#Post("login/verify")
#HttpCode(201)
#ApiResponse({ description: "returns JWT for verified login attempt" })
async verify(
#Body() method: VerificationDto,
#Req() req: Request,
#Res({ passthrough: true }) res: Response
) {
const { accessToken } = await this.userService.verifyLogin(method);
const origin = req.get("origin");
this.loggerService.log(`origin: ${origin}`);
res
.set("Access-Control-Allow-Credentials", "true")
.set("Access-Control-Allow-Origin", origin)
.cookie("accessToken", accessToken, {
expires: new Date(new Date().getTime() + 60 * 1000 * 60 * 2),
sameSite: "none",
secure: true,
httpOnly: false,
});
return {
accessToken,
refreshToken,
};
}
Here is my useAuth component in Next.js
import React from "react";
import jwtDecode from "jwt-decode";
import nookies from "nookies";
import { redirect } from "../../services/redirect";
import { GetServerSideProps, NextPage } from "next";
export interface User {
accessToken: string;
email: string;
exp: number;
iat: number;
id: string;
name: string;
roles: Array<string>;
}
const AuthContext = React.createContext<User>(null as unknown as User);
const loginRoute = `/login`;
export const authenticate = (
getServerSidePropsInner: GetServerSideProps = async () => ({ props: {} })
) => {
const getServerSideProps: GetServerSideProps = async ctx => {
const { req, res } = ctx;
if (!req.headers.cookie) {
console.log("no cookie found");
redirect(ctx, loginRoute);
return { props: {} };
}
const { accessToken } = nookies.get(ctx);
console.log(accessToken);
let user = null;
try {
user = {
accessToken,
...(jwtDecode(accessToken as string) as object),
};
} catch (e) {
console.log(e);
redirect(ctx, loginRoute);
}
const result = await getServerSidePropsInner(ctx);
return {
...result,
props: {
user,
//#ts-ignore
...result.props,
},
};
};
return getServerSideProps;
};
export const withAuth = (C: NextPage) => {
const WithAuth = (props: any) => {
const { user, ...appProps } = props;
return (
<AuthContext.Provider value={user}>
<C {...appProps} />
</AuthContext.Provider>
);
};
WithAuth.displayName = `WithAuth(${C.displayName})`;
return WithAuth;
};
export default withAuth;
export const useAuth = (): User => React.useContext(AuthContext);
I am using axios with the following login request
verifyLogin: ({ code, email }: { code: string; email: string }) => {
return axios(`${apiURI}/user/login/verify`, {
method: `POST`,
withCredentials: true,
headers: {
"Content-Type": "application/json",
},
data: {
code: code,
email: email,
},
});
},
Setup works with localhost. It adds a http cookie which is read by the next.js application.
However, when deploying my Nest.js app to Heroku, the cookie does not seem to send to the next application. I have tried adding different values for the CookieOptions
sameSite: "none",
secure: true,
httpOnly: false,
However, this did not help either.
Any help is much appreciated as I am fighting with this for days.

TypeError: User.comparePassword is not a function. Comes up with Postman

I'm trying to get my login component on the server side to work, but it keeps giving me this one error over and over. "TypeError: User.comparePassword is not a function" I had it working in postman before, but I can't figure out why it broke now. I'm making an ecommerce site, so I'm excluding code that has stuff to do with the rest of the site.
[user.js - my routing and where the error is being presented.]
const { User, validateUser } = require("../models/user.js");
const bcrypt = require("bcrypt");
const config = require("config");
const jwt = require("jsonwebtoken");
const auth = require("../middleware/auth");
const express = require("express");
const router = express.Router();
//get users
router.get("/", async (req, res) => {
try {
const users = await User.find();
return res.send(users);
} catch (ex) {
return res.status(500).send(`Internal server Error: ${ex}`);
}
});
//get a user
router.get("/:userId", async (req, res) => {
try {
const user = await User.findById(req.params.userId);
return res.send(user);
} catch (ex) {
return res.status(500).send(`Internal server Error: ${ex}`);
}
});
//new user
router.post("/register", async (req, res) => {
try {
const { error } = validateUser(req.body);
if (error) return res.status(500).send(error.details[0].message);
let user = await User.findOne({ email: req.body.email });
if (user) return res.status(400).send("User already registered.");
const salt = await bcrypt.genSalt(10);
user = new User({
name: req.body.name,
email: req.body.email,
password: await bcrypt.hash(req.body.password, salt),
});
await user.save();
const token = jwt.sign(
{ _id: user._id, name: user.name },
config.get("jwtSecret")
);
return res
.header("x-auth-token", token)
.header("access-control-expose-headers", "x-auth-token")
.send({ _id: user._id, name: user.name, email: user.email });
} catch (ex) {
return res.status(500).send(`InternalServerError:${ex}`);
}
});
router.get("/auth", auth, (req, res) => {
res.status(200).json({
_id: req.user._id,
isAdmin: req.user.role === 0 ? false : true,
isAuth: true,
email: req.user.email,
name: req.user.name,
role: req.user.role,
image: req.user.image,
cart: req.user.cart,
history: req.user.history,
});
});
router.post("/login", (req, res) => {
User.findOne({ email: req.body.email }, (err, user) => {
if (!User)
return res.json({
loginSuccess: false,
message: "Auth failed, email not found",
});
});
User.comparePassword(req.body.password, (err, isMatch) => {
if (!isMatch)
return res.json({ loginSuccess: false, message: "Wrong password" });
user.generateToken((err, user) => {
if (err) return res.status(400).send(err);
res.cookie("w_authExp", User.tokenExp);
res.cookie("w_auth", User.token).status(200).json({
loginSuccess: true,
userId: user._id,
});
});
});
router.get("/logout", auth, (req, res) => {
User.findOneAndUpdate(
{ _id: req.user._id },
{ token: "", tokenExp: "" },
(err, doc) => {
if (err) return res.json({ success: false, err });
return res.status(200).send({
success: true,
});
}
);
});
});
[User.js - Userschema]
const mongoose = require('mongoose');
const Joi = require('joi');
const cors = require('cors');
const config = require('config');
const jwt = require('jsonwebtoken');
const { productSchema } = require('./Product');
const { reviewSchema } = require('./review');
const userSchema = new mongoose.Schema({
name: { type: String, required: true, minlength: 5, maxlength: 50},
email: {type: String, unique: true, required: true, minlength: 5, maxlength: 255},
password: {type: String, required: true, maxlength: 1024, minlength: 5},
timestamp: { type: Date, default: Date.now() },
cart: {type: [productSchema], default: []},
newSalePost: {type: [productSchema], default: []},
review: {type: [reviewSchema], default: []},
image: {type: String, required: true}
});
const User = mongoose.model('User', userSchema);
userSchema.methods.generateAuthToken = function () {
return jwt.sign({_id: this._id, name: this.name, isAdmin: this.isAdmin}, config.get('jwtSecret'));
};
function validateUser(user){
const schema = Joi.object({
name: Joi.string().min(5).max(50).required(),
email: Joi.string().min(5).max(255).required().email(),
password: Joi.string().min(5).max(1024).required(),
});
return schema.validate(user);
}
userSchema.statics.findByToken = function (token, cb) {
var user = this;
jwt.verify(token, 'secret', function (err, decode) {
user.findOne({ "_id": decode, "token": token }, function (err, user) {
if (err) return cb(err);
cb(null, user);
})
})
}
exports.User = User;
exports.validateUser = validateUser;
exports.userSchema = userSchema;

How to insert data in Sequelize

In my Express app, I have to insert a new table record to MySQL database. I'm using Sequelize as the ORM. However, with the following setup , I couldn't do that. When I send a POST request to /users/register method(UserController.signup() is set to be executed at this route), it is waiting forever for a response in POSTman. I tried returning a string from UserController.signup() and then the request was working fine.
Why can't I insert a record into database? Every help is highly appreciated.
UserController.js
var User = require('../models/user')
module.exports = {
signUp: (fname,email,password) => {
User.create({ firstName: fname, email: email, password: password }).then(user => {
console.log("New auto-generated ID:", user.id);
});
}
}
models/user.js
'use strict';
module.exports = (sequelize, DataTypes) => {
const User = sequelize.define('User', {
firstName: DataTypes.STRING,
email: DataTypes.STRING,
password: DataTypes.STRING
}, {});
User.associate = function(models) {
// associations can be defined here
};
return User;
};
app.js
var createError = require('http-errors');
var express = require('express');
var db = require('./database')
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var Router = require('./routes/index');
var app = express();
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(Router);
db.authenticate()
.then(() => {
console.log('Connection has been established successfully.');
})
.catch(err => {
console.error('Unable to connect to the database:', err);
});
app.use(function(req, res, next) {
next(createError(404));
});
app.use(function(err, req, res, next) {
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
res.status(err.status || 500);
});
module.exports = app;
database.js
const Sequelize = require('sequelize');
const sequelize = new Sequelize('test', 'root', '', {
host: 'localhost',
dialect: 'mariadb'
});
module.exports = sequelize
EDIT
I changed models/user.js as follows.
'use strict';
var sequelize = require('../database')
var Sequelize = require('sequelize')
const User = sequelize.define('User', {
firstName: Sequelize.STRING,
email: Sequelize.STRING,
password: Sequelize.STRING
}, {});
User.associate = function(models) {
// associations can be defined here
};
module.exports = User;
Add an id attribute to your User model. You're trying to access the value from the User model but it's not declared. It will still be auto-generated for you. Try something like this:
Model user.js
const User = sequelize.define('User', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: DataTypes.INTEGER
},
firstName: DataTypes.STRING,
email: DataTypes.STRING,
password: DataTypes.STRING
}, {});
Migration migration:generate --name createUser
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('Users', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
firstName: {
type: Sequelize.STRING
},
email: {
type: Sequelize.STRING
},
password: {
type: Sequelize.STRING
},
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('Users');
}