I am having trouble after I deployed my app (backend on Heroku and frontend on Netlify). It was working fine in localhost earlier
While I was making the API request (Login or SIgnUP) from frontEnd, it is showing me the error.
Cannot read properties of undefined (reading 'findOne')
The Heroku Log is said that it is Connected to Mongo Successfully
, but still I am getting this error there.
I had created a remote MongoDB cloud on MOngoAtlas like this,
And I had connected it in my db.js
like this
const mongoose = require("mongoose");
//const mongoURI = "mongodb://localhost:27017/?readPreference=primary&appname=MongoDB%20Compass&ssl=false";
const mongoURI = "mongodb+srv://mohit_maroliya:Zker42FNU.buD_E@cluster0.n03hm.mongodb.net/myFirstDatabase?retryWrites=true&w=majority"
const connectToMongo = async() => {
mongoose.connect(mongoURI, {useNewUrlParser: true}, ()=> {
console.log("Connected to Mongo Successfully!");
})
}
module.exports = connectToMongo;
So I think that my Mongo connection is connected but not to this database.
Also in the Google Console, it is showing Unexpected token i in JSON at position 0
I am sharing the code of the files involved
Index.js
const connectToMongo = require('./db');
const express = require('express');
connectToMongo();
var cors = require('cors')
const app = express()
// const port = 5000
//to use req body
app.use(cors())
app.use(express.json())
//Available routes
app.use('/api/auth',require('./routes/auth'));
app.use('/api/notes',require('./routes/notes'));
app.listen(process.env.PORT , () => {
console.log(`my-notebook backend listening at https://my-notebook-mohit.herokuapp.com:${process.env.PORT }`)
})
auth.js
const express = require("express");
const { body, validationResult } = require("express-validator");
const router = express.Router();
const { User } = require("../models/User");
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
const JWT_SECRET = "mohitisagood$boy";
const fecthUser = require("../middleware/fetchUser");
//ROUTE 1 :Creating a User :POST - "/api/auth/createuser"
router.post(
"/createuser",
[
body("name", "Name must have at least 3 characters").isLength({ min: 3 }),
body("email", "Enter a valid email").isEmail(),
],
async (req, res) => {
let success = false;
//If there are errors, then return bad request + Errors
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({success, errors: errors.array() });
}
try {
//Check whether email exists
//let user;
let user = await User.findOne({ email: req.body.email });
console.log("user.nemail = " + user);
if (user) {
//console.log(user.email);
return res.status(400).json({success, error: "Email Already Taken" });
}
//hashing the password here
const salt = await bcrypt.genSalt(10);
const secPass = await bcrypt.hash(req.body.password, salt);
//user is created
user = await User.create({
name: req.body.name,
email: req.body.email,
password: secPass,
});
//passing the id as data to make jwt token
const data = {
user: {
id: user.id,
},
};
const authToken = jwt.sign(data, JWT_SECRET);
//console.log(authToken)
success = true;
//res.json(user);
res.json({success, authToken });
} catch (error) {
console.log(error.message);
res.status(500).send("internal server error");
}
}
);
//ROUTE 2 :Authenticating a User :POST - "/api/auth/login"
router.post(
"/login",
body("email", "Enter a valid email").isEmail(),
async (req, res) => {
//If there are errors, then return bad request + Errors
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const { email, password } = req.body;
let success = false;
try {
let user = await User.findOne({ email });
// console.log("user - "+user)
if (!user) {
res.status(400).json({success,error:"Login with correct credentials!"});
}
//compare the pwd bw 'hash of pwd entered' & 'hash from your pwdDB'
const passwordCompare = await bcrypt.compare(password, user.password);
if (!passwordCompare) {
res.status(400).json({success,error:"Login with correct credentials!"});
}
//nodemon crashes whenever PASSWORD === NULL
const payload = {
user: {
id: user.id,
},
};
const authToken = jwt.sign(payload, JWT_SECRET);
success = true;
res.json({ success, authToken });
} catch (error) {
console.log(error.message);
res.status(500).send("Internal Server Error");
}
}
);
module.exports = router;
Model (User.js)
const mongoose = require("mongoose");
const { Schema } = mongoose;
const UserSchema = new Schema({
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
},
password: {
type: String,
required: true,
validate(value) {
if(value.length < 5) {
throw new Error( "Minimum length is 5 characters");
}
else if (!value.match(/\d/) || !value.match(/[a-zA-Z]/) ) {
throw new Error(
"Password must contain at least one letter and one number"
);
}
}
},
date: {
type: Date,
default: Date.now,
},
});
const User = mongoose.model("users", UserSchema);
module.exports = User;
Login.js (frontend)
import React, { useState } from "react";
import { useHistory } from "react-router-dom";
import imgpath from "../assets/notepic.jpg";
import { motion } from "framer-motion";
const Login = (props) => {
let history = useHistory();
const [credentials, setCredentials] = useState({ email: "", password: "" });
const onChange = (e) => {
setCredentials({ ...credentials, [e.target.name]: e.target.value });
//input mei value typed ho sake,jaise jaise value change ho vese-vese note me set ho jaye
};
const goToSignup = () => {
history.push("/signup");
};
const handleSubmit = async (e) => {
e.preventDefault();
const response = await fetch(`https://my-notebook-mohit.herokuapp.com:/api/auth/login`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
email: credentials.email,
password: credentials.password,
}),
});
const json = await response.json();
if (json.success === true) {
//storing the authtoken
localStorage.setItem("token", json.authToken);
props.showAlert("User logged in successfully", "info");
history.push("/");
} else {
props.showAlert("invalid Credentials", "danger");
}
console.log(json);
};
return (
<motion.div className="container" id="manku" animate={{scale:[0.5,1]}} transition={{times:[0.1,0.4], ease:'easeInOut'}}>
<div id="picturebody">
<img src={imgpath} alt="note-pic" width="100%" />
</div>
<div id="loginbody">
<div className="mt-3">
<h2 className="my-3"> Login to continue</h2>
<form onSubmit={handleSubmit} className="login-form">
.
.
.
</form>
<div className="text-center my-5" id="bottom-text">
mynotebook
</div>
</div>
</div>
</motion.div>
);
};
export default Login;
2022-01-26T12:04:28.024784+00:00 heroku[web.1]: Starting process with command `npm start`
2022-01-26T12:04:29.075584+00:00 app[web.1]:
2022-01-26T12:04:29.075596+00:00 app[web.1]: > my-notebook-backend@1.0.0 start
2022-01-26T12:04:29.075596+00:00 app[web.1]: > node index.js
2022-01-26T12:04:29.075596+00:00 app[web.1]:
2022-01-26T12:04:29.561386+00:00 app[web.1]: my-notebook backend listening at https://my-notebook-mohit.herokuapp.com:38751
2022-01-26T12:04:29.561856+00:00 app[web.1]: Connected to Mongo Successfully!
2022-01-26T12:04:29.766495+00:00 heroku[web.1]: State changed from starting to up
2022-01-26T12:04:05.000000+00:00 app[api]: Build started by user maroliya.1@iitj.ac.in
2022-01-26T12:04:24.985213+00:00 app[api]: Release v32 created by user maroliya.1@iitj.ac.in
2022-01-26T12:04:24.985213+00:00 app[api]: Deploy c9d42533 by user maroliya.1@iitj.ac.in
2022-01-26T12:04:25.000000+00:00 app[api]: Build succeeded
2022-01-26T12:06:05.906508+00:00 heroku[router]: at=info method=OPTIONS path="/api/auth/login" host=my-notebook-mohit.herokuapp.com request_id=a4c47a5b-a85b-469e-a595-f1ed356e2373 fwd="27.56.201.36" dyno=web.1 connect=0ms service=5ms status=204 bytes=301 protocol=https
2022-01-26T12:06:06.155157+00:00 app[web.1]: Cannot read properties of undefined (reading 'findOne')
2022-01-26T12:06:06.163135+00:00 heroku[router]: at=info method=POST path="/api/auth/login" host=my-notebook-mohit.herokuapp.com request_id=02849e70-a653-4751-a6dc-de73cf7a2bf2 fwd="27.56.201.36" dyno=web.1 connect=0ms service=34ms status=500 bytes=272 protocol=https
2022-01-26T12:06:21.493881+00:00 heroku[router]: at=info method=POST path="/api/auth/createuser" host=my-notebook-mohit.herokuapp.com request_id=27e52b6b-6931-4797-9296-2a81cf1c8399 fwd="27.56.201.36" dyno=web.1 connect=0ms service=4ms status=500 bytes=272 protocol=https
2022-01-26T12:06:21.291315+00:00 heroku[router]: at=info method=OPTIONS path="/api/auth/createuser" host=my-notebook-mohit.herokuapp.com request_id=25d391ad-d14c-4999-b9da-18c1328ce0cd fwd="27.56.201.36" dyno=web.1 connect=0ms service=1ms status=204 bytes=301 protocol=https
2022-01-26T12:06:21.491373+00:00 app[web.1]: Cannot read properties of undefined (reading 'findOne')
in the website of mongodb, this is the way to connect to a database.
async function main(){
/**
* Connection URI. Update <username>, <password>, and <your-cluster-url> to reflect your cluster.
* See https://docs.mongodb.com/ecosystem/drivers/node/ for more details
*/
const uri = "mongodb+srv://<username>:<password>@<your-cluster-url>/test?retryWrites=true&w=majority";
const client = new MongoClient(uri);
try {
// Connect to the MongoDB cluster
await client.connect();
// Make the appropriate DB calls
await listDatabases(client);
} catch (e) {
console.error(e);
} finally {
await client.close();
}
}
main().catch(console.error);
and this is the link for reference
i think the problem is with require/export
you can either chagnge:
const { User } = require("../models/User");
to:
const User = require("../models/User");
or you can export the user like this:
module.exports.User = User;
instead of:
module.exports = User;
I think your application setup initialization is have some problem in a race condition. Have you ever try to wrap your initialization like below.
const connectToMongo = require('./db');
const express = require('express');
const start = async () => {
await connectToMongo(); // Need to await this Promise before listen any HTTP request
var cors = require('cors')
const app = express()
// const port = 5000
//to use req body
app.use(cors())
app.use(express.json())
//Available routes
app.use('/api/auth',require('./routes/auth'));
app.use('/api/notes',require('./routes/notes'));
app.listen(process.env.PORT , () => {
console.log(`my-notebook backend listening at https://my-notebook-mohit.herokuapp.com:${process.env.PORT }`)
})
start();
You also have to await the Promise from mongoose.connect too
const mongoose = require("mongoose");
//const mongoURI = "mongodb://localhost:27017/? readPreference=primary&appname=MongoDB%20Compass&ssl=false";
const mongoURI = "mongodb+srv://mohit_maroliya:Zker42FNU.buD_E@cluster0.n03hm.mongodb.net/myFirstDatabase?retryWrites=true&w=majority"
const connectToMongo = async () => {
await mongoose.connect(mongoURI, {useNewUrlParser: true}, ()=> {
console.log("Connected to Mongo Successfully!");
})
}
module.exports = connectToMongo;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.