findOne is not a function - express

I am trying to create a model using Sequelize and mysql db.I am trying to post to '/students/register' it keeps giving me an error saying findOne is not a function. I tried requiring my sql but it's not working ..I also tried a different function like findAll and still not working.what seems to be the problem
const Sequelize = require('sequelize');
module.exports = function (sequelize, Sequelize) {
const Stundet = sequelize.define(
'student', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
name: {
type: Sequelize.STRING
},
email: {
type: Sequelize.STRING
},
password: {
type: Sequelize.STRING
},
created: {
type: Sequelize.DATE,
defaultValue: Sequelize.NOW
}
}, {
timestamps: false
});
module.exports = Stundet;
}
routes
const Student_Info = require("../models/students")
student.post('/register', (req, res) => {
const dataToday = new Date()
const studentData = {
name: req.body.name,
email: req.body.email,
password: req.body.password,
created: dataToday
}
Student_Info.findOne({
where: {
email: req.body.email
}
})
.then(student => {
if (!student) {
bcrypt.hash(req.body.password, 10, (err, hash) => {
studentData.password = hash
Student_Info.create(studentData)
.then(student => {
res.json({
status: student.email + 'registered'
})
})
.catch(err => {
res.send('error' + err)
})
})
} else {
res.json({
error: 'Student already registered'
})
}
})
.catch(err => {
res.send('error' + err)
})
})
module.exports = student;

When you use module.exports, you should return Stundet. You already export the whole function. And I think you should pass DataTypes instead of Sequelize.
Something like this:
module.exports = function (sequelize, DataTypes) {
const Stundet = sequelize.define(
//...
return Stundet;
}
So in your route in order to use your model:
const Sequelize = require('sequelize');
const DataTypes = sequelize.DataTypes;
let sequelize = new Sequelize(...);
const Student = require('../models/students')(sequelize, DataTypes);

I suspect that your Student_Info is null. Does you application successfully connect to the database? It helps to log... e.g.
sequelizeDB
.authenticate()
.then(() => {
console.log('Yes! DB Connection);
...
})
.catch(err => {
console.error('No! Unable to connect to DB', err);
});
... and IMHO the code reads better when you name the DB instance something other than "sequelize".

Related

Freecodecamp execrise tracker unable to fetch date from data base

Unaable to fetch data from get request : /api/users/:_id/logs
url passed to this request : https://boilerplate-project-exercisetracker.sushilgupta4.repl.co/api/users/63a42aa0beed29d45418f2d5/logs?from=2022-10-10&to=2022-12-30&limit=2
link to my project : https://replit.com/#SushilGupta4/boilerplate-project-exercisetracker
As when I save the data for exercise for particular user the date is saved in the format of 2022-11-05T00:00:00.000+00:00.
But When I recevice date from the user request then convert date to new Date(date) and date is converted in the format of 2022-10-10T00:00:00.000Z
I think if able to change format of either one my code will work. Please look into to code and please tell me how can solve this problem.
This is the project from freecodecamp which i need complete in order to get back-end certificate.
https://www.freecodecamp.org/learn/back-end-development-and-apis/back-end-development-and-apis-projects/exercise-tracker
const express = require('express')
const app = express()
const cors = require('cors')
const mongoose = require('mongoose')
require('dotenv').config()
try {
mongoose.connect(process.env.MANGO_URI, { useNewUrlParser: true, useUnifiedTopology: true });
console.log('db connected')
} catch (err) {
console.log(err)
}
const personSchema = new mongoose.Schema({
username: {
type: String,
require: [true, 'username must be provided'],
unique: true
},
})
const exerciseSchema = new mongoose.Schema({
userId: {
type: String,
require: [true, 'userId must be provided']
},
username: {
type: String,
require: [true, 'username must be provided']
},
description: {
type: String,
require: [true, 'desc must be provided']
},
duration: {
type: Number,
require: [true, 'Duration must be provided']
},
date: {
type: String,
require: [true, 'date must be provided']
},
})
const Person = mongoose.model("Person", personSchema)
const Exercise = mongoose.model("Exercise", exerciseSchema)
app.use(cors())
app.use(express.static('public'))
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res) => {
res.sendFile(__dirname + '/views/index.html')
});
app.post('/api/users', function(req, res) {
const username = req.body.username
const data = new Person({ username: username })
data.save((err, data) => {
if (err) {
res.json("username already Taken")
} else {
res.json({ username: data.username, _id: data._id })
}
})
})
app.get('/api/users', (req, res) => {
Person.find({}, (err, data) => {
if (!data) {
res.send("No user")
} else {
res.json(data)
}
})
})
app.post('/api/users/:_id/exercises', (req, res) => {
const _id = req.body[':_id']
const { description, duration, date } = req.body
console.log(new Date(date).toISOString())
let formatDate = new Date(date).toISOString()
console.log("format date" + formatDate)
Person.findById(_id, (err, data) => {
if (!data) {
res.send("User Not found")
} else {
const username = data.username
const addExercise = new Exercise({ userId: _id, username, description, duration, date: formatDate })
addExercise.save((err, user) => {
if (err) console.log(err)
res.json({ username: username, description: user.description, duration: user.duration, date: user.date.toDateString, _id })
})
}
})
})
app.get('/api/users/:_id/logs', (req, res) => {
const userId = req.params._id
const _id = userId
let { from, to, limit } = req.query
let filter = { userId }
let dateFilter = {}
if (from) {
from = new Date(from)
from = from.slice(23)
dateFilter['&gte'] = from
console.log(from)
}
if (to) {
dateFilter['&lte'] = new Date(to)
}
if (from || to) {
filter.date = dateFilter
}
console.log(filter)
Person.findById({ _id }, (err, data) => {
if (!data) {
res.send("userId not found")
} else {
console.log("found the id user")
const username = data.username
//{date: {$gte: new Date(from), $lte:new Date (to)}}
Exercise.find(filter).limit(limit).exec((err, data) => {
console.log("found user exericse")
if (err) console.log(err)
//console.log(data)
let customdata = data.map(items => {
let formattedDate = new Date(items.date).toDateString()
return { description: items.description, duration: items.duration, date: formattedDate }
})
if (!data) {
res.json({
"_id": userId,
"username": username,
"count": 0,
"log": []
})
} else {
console.log("inside")
res.json({
"_id": userId,
"username": username,
"count": data.length,
"log": customdata
})
}
})
}
})
})
const listener = app.listen(process.env.PORT || 3000, () => {
console.log('Your app is listening on port ' + listener.address().port)
})
I was expecting how can i fetch the data from that get request or how can i change the date format.

How can I use this variable on Vue.js?

I have a problem trying to use a variable inside my async function in Vue
this is in methods:
methods: {
async editar(event) {
db.collection("products").doc(event).get().then((doc) => {
const productData = doc.data();
console.log("Nombre: ", productData.nombre); /* this */
console.log("Stock: ", productData.stock);
}).catch((error) => {
console.log("Error getting document:", error);
});
const alert = await alertController.create({
cssClass: 'alertClass',
header: 'Editar producto',
message: '¿Qué deseas cambiar?',
inputs: [
{
name: 'nuevoNombre',
type: 'text',
placeholder: 'Nombre',
value: '' /* here */
},
{
name: 'nuevoStock',
type: 'number',
placeholder: 'Stock'
}
],
buttons: [
{
text: 'Cancelar',
role: 'cancel',
cssClass: 'secondary',
handler: () => {
console.log('Cancelado');
},
},
{
text: 'Aceptar',
handler: (data) => {
console.log('Se actualiza el doc: ' + event);
db.collection("products").doc(event).update({
nombre: data.nuevoNombre,
stock: data.nuevoStock
}).then(() => {
console.log("Nuevo nombre:", data.nuevoNombre);
console.log("Nuevo stock:", data.nuevoStock);
window.location.reload();
}).catch((error) => {
console.log("Error al intentar cambiar los valores", error);
});
},
},
],
});
return alert.present();
}
}
I want to use productData.nombre in the value inside the alertController. I was trying a lot of things but nothing works :(
I hope you can understand my question
const productData = doc.data();
const defined productData only can be reference at cloest scope.
At your situation, scope is
db.collection("products").doc(event).get().then((doc) => {
const productData = doc.data(); // only referenced in this scope (arrow function)
console.log("Nombre: ", productData.nombre); /* this */
console.log("Stock: ", productData.stock);
})
You can define variable before give it a value like this
async function editar(event) {
let productData;
db.collection("products")
.doc(event)
.get()
.then((doc) => {
productData = doc.data();
console.log("Nombre: ", productData.nombre); /* this */
console.log("Stock: ", productData.stock);
})
.catch((error) => {
console.log("Error getting document:", error);
});
const alert = await alertController.create({
// your code
})
}
db.collection("products") seems like an async function, using await before calling it, or you will miss db data since it's not ready.
You should declare variable outside your function which getting db data first, due to javascript scope
Here is a similar easy example on codepen

User authentication error using express not working

So I'm having trouble authenticating a user login using express for the backend. If I do a simple res.send I could get a response in postman. but if I do a check if the user and password check and generate a token if says error 401 invalid usernames and password. mind the tokens work for register and update profiles. I also attached the user schema.
Simple Approach
const authUser = asyncHandler(async (req, res) => {
const { email, password } = req.body
res.send({ email, password })
})
When I try to check and generate a token
const authUser = asyncHandler(async (req, res) => {
const { email, password } = req.body
const user = await User.findOne({ email })
if (user && (await user.matchPassword(password))) {
res.json({
_id: user._id,
name: user.name,
email: user.email,
isAdmin: user.isAdmin,
token: generateToken(user._id),
})
} else {
res.status(401)
throw new Error('Invalid Email or password')
}
})
Also here's my user schema using mongoose and added a function to check password since in the database it's encrypted using bcrypt.js
import mongoose from 'mongoose'
import bcrypt from 'bcryptjs'
const userSchema = mongoose.Schema(
{
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
unique: true,
},
password: {
type: String,
required: true,
},
isAdmin: {
type: Boolean,
required: true,
default: false,
},
},
{
timestamps: true,
}
)
userSchema.methods.matchPassword = async function (enteredPassword) {
return await bcrypt.compare(enteredPassword, this.password)
}
const User = mongoose.model('User', userSchema)
export default User
You see, your code is absolutely correct, but only if you have saved the user correctly in your model at the first. In addition, the password used during storage is hashed in the same way and from the same module.
Now you have to change your checking terms because there may not really be a user with this email in the database to match your password and return true value.
import mongoose from 'mongoose'
import bcrypt from 'bcryptjs'
const userSchema = mongoose.Schema(
{
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
unique: true,
},
password: {
type: String,
required: true,
},
isAdmin: {
type: Boolean,
required: true,
default: false,
},
},
{
timestamps: true,
}
)
userSchema.pre('save', function (next) {
if (this.password) {
bcrypt.hash(this.password, bcrypt.genSaltSync(15), (err, hash) => {
if (err) console.log(err);
this.password = hash;
next();
});
}
}
userSchema.methods.Save = async (data) => {
let model=new User(data)
await model.save();
}
userSchema.methods.matchPassword = async function (enteredPassword) {
return await bcrypt.compare(enteredPassword, this.password)
}
const User = mongoose.model('User', userSchema)
export default User
and update this code:
const authUser = asyncHandler(async (req, res) => {
const { email, password } = req.body
const user = await User.findOne({ email })
if (user) {
if(await user.matchPassword(password)) {
res.json({
_id: user._id,
name: user.name,
email: user.email,
isAdmin: user.isAdmin,
token: generateToken(user._id),
})
} else {
res.status(401)
throw new Error('Invalid password')
}
} else {
res.status(401)
throw new Error('Invalid Email')
}
})
Now you know which part of the job is the problem. No user or no wrist password

mongoose code only works if I make 2 http requests

Main objective:
On call to route I either get a new or update existing CartItem object.
The Object amount and total are passed in the middleware so the object total gets recalculated.
The Schema seems to properly apply its middleware properly on the first request (based on the console logs).
However I only get an object with the updated total if I make another http request.
This is beyond my understanding and I would appreciate some assistance.
Schema:
const mongoose = require('mongoose');
const uniqueValidator = require('mongoose-unique-validator');
const Product = require('./Product');
const Cart = require('./Cart');
const refIsValid = require('../middleware/refIsValid');
const cartItemSchema = mongoose.Schema({
name: { type: String },
productRef: { type: mongoose.Schema.Types.ObjectId, ref: 'Product', required: true },
cartRef: { type: mongoose.Schema.Types.ObjectId, ref: 'Cart', required: true },
price: { type: Number, default: 0 },
imgUrl: { type: String },
amount: { type: Number, required: true },
total: { type: Number, default: 0 },
active: { type: Boolean, default: true },
uniqueName: { type: String, unique: true },
});
cartItemSchema.path('productRef').validate((value, respond) => {
return refIsValid(value, respond, Product);
}, 'Invalid product ref.');
cartItemSchema.path('cartRef').validate((value, respond) => {
return refIsValid(value, respond, Cart);
}, 'Invalid cart ref.');
cartItemSchema.path('price').get(function(num) {
return num.toFixed(2);
});
cartItemSchema.pre('save', async function(next) {
const refCart = await Cart.findById(this.cartRef).lean().exec();
const refProduct = await Product.findById(this.productRef).lean().exec();
const uniqueName = `${refProduct._id}_${refCart._id}`;
this.name = refProduct.name;
this.price = refProduct.price;
this.imgUrl = refProduct.imgUrl;
this.total = (this.price * this.amount).toFixed(2);
this.uniqueName = uniqueName;
next();
});
cartItemSchema.post('findOneAndUpdate', async function(result) {
console.log('TCL: result', result);
await result.save(function(err) {
if (err) {
console.error('ERROR!');
}
});
console.log('TCL: docToUpdate', result);
});
cartItemSchema.plugin(uniqueValidator);
module.exports = mongoose.model('cartItem', cartItemSchema);
controller:
static async updateOrCreate(req, res, next) {
try {
let { cartRef, productRef, amount } = req.body;
let options = { upsert: true, new: true, setDefaultsOnInsert: true };
// const uniqueName = `${productRef._id}_${cartRef._id}`;
const updateOrCreate = await CartItem.findOneAndUpdate(
{ cartRef: cartRef, productRef: productRef },
{ amount: amount },
options,
);
if (updateOrCreate) {
const result = await CartItem.findById(updateOrCreate._id);
console.log('TCL: CartItemController -> updateOrCreate -> result', result);
res.status(200).json({
isNew: false,
message: 'item updated',
productItem: result,
});
return;
}
} catch (error) {
error.statusCode = 500;
next(error);
}
}

Sequelize Model class reference error in express application

sq.js:
var Sequelize = require('sequelize');
var sequelize = new Sequelize('postgres://chandan:duvarko315#localhost:5432/diary');
var User = sequelize.define('user', {
username: {
type: Sequelize.STRING,
field: 'username' // Will result in an attribute that is firstName when user facing but first_name in the database
},
password: {
type: Sequelize.STRING
}
},{
timestamps: false,
});
User.sync({force: true}).then(function () {
// Table created
});
module.exports = User;
app.js:
var seq = require('./routes/sq');
passport.use(new passportLocal.Strategy(function(username,password, done){
User.findOne({username: username}, function (err, user) {
if (err) { return done(err); }
if (!user) {
return done(null, false, { message: 'Incorrect username.' });
}
if (!user.validPassword(password)) {
return done(null, false, { message: 'Incorrect password.' });
}
return done(null,{ id:username, name:username});
});
}));
I am getting the error: ReferenceError: User is not defined
Its because you have declared the user model as seq in app.js. Change your declaration to:
var User = require('./routes/sq');
The variable Useronly lives in sq.js