Reputation: 7752
I'm following this course on Udemy with ends with completing this app on github.
I'm getting stuck on the 10th lesson where I need to create a User Registration API and then test by making an AJAX POST request, when I try to make the fetch
POST I get this error message.
When I try testing this with the node debugger, i.e. node --inspect=0.0.0.0:9229 server.js
I see the code is not stopping in line 29 to execute the .then
promise below.
This seems to indicate that findOne()
is not returning a Promise as it should, even though I can see from the course I'm doing on Udemy that it is. Also, the Mongoose documentation says it returns a Promise too.
I've uploaded all the code to here on GitHub so that it is easier to reproduce. But all the relevant code and logs are below too.
This is the output from the server console, there are no useful error messages after I make the fetch request...
in ~/devconnector
$ (master) npm run debug
> [email protected] debug /Users/holly/devconnector
> node --inspect=0.0.0.0:9229 server.js
Debugger listening on ws://0.0.0.0:9229/22164c98-654b-4056-9bae-9a8b8cf96ddf
For help see https://nodejs.org/en/docs/inspector
(node:1892) DeprecationWarning: current URL string parser is deprecated, and will be removed in a future version. To use the new parser, pass option { useNewUrlParser: true } to MongoClient.connect.
Server running on port 5000
MongoDB Connected
Debugger attached.
Here are the mongo DB logs, nothing is output after I make the fetch request on the frontend...
$ mongod
2018-09-09T12:12:03.431+0100 I CONTROL [main] Automatically disabling TLS 1.0, to force-enable TLS 1.0 specify --sslDisabledProtocols 'none'
2018-09-09T12:12:03.445+0100 I CONTROL [initandlisten] MongoDB starting : pid=1932 port=27017 dbpath=/data/db 64-bit host=hollys-MacBook-Pro.local
2018-09-09T12:12:03.445+0100 I CONTROL [initandlisten] db version v4.0.1
2018-09-09T12:12:03.445+0100 I CONTROL [initandlisten] git version: 54f1582fc6eb01de4d4c42f26fc133e623f065fb
2018-09-09T12:12:03.445+0100 I CONTROL [initandlisten] allocator: system
2018-09-09T12:12:03.445+0100 I CONTROL [initandlisten] modules: none
2018-09-09T12:12:03.445+0100 I CONTROL [initandlisten] build environment:
2018-09-09T12:12:03.445+0100 I CONTROL [initandlisten] distarch: x86_64
2018-09-09T12:12:03.445+0100 I CONTROL [initandlisten] target_arch: x86_64
2018-09-09T12:12:03.445+0100 I CONTROL [initandlisten] options: {}
2018-09-09T12:12:03.446+0100 I STORAGE [initandlisten] Detected data files in /data/db created by the 'wiredTiger' storage engine, so setting the active storage engine to 'wiredTiger'.
2018-09-09T12:12:03.446+0100 I STORAGE [initandlisten] wiredtiger_open config: create,cache_size=7680M,session_max=20000,eviction=(threads_min=4,threads_max=4),config_base=false,statistics=(fast),log=(enabled=true,archive=true,path=journal,compressor=snappy),file_manager=(close_idle_time=100000),statistics_log=(wait=0),verbose=(recovery_progress),
2018-09-09T12:12:04.105+0100 I STORAGE [initandlisten] WiredTiger message [1536491524:105407][1932:0x7fffa4bb1340], txn-recover: Main recovery loop: starting at 7/8320
2018-09-09T12:12:04.190+0100 I STORAGE [initandlisten] WiredTiger message [1536491524:190433][1932:0x7fffa4bb1340], txn-recover: Recovering log 7 through 8
2018-09-09T12:12:04.247+0100 I STORAGE [initandlisten] WiredTiger message [1536491524:247607][1932:0x7fffa4bb1340], txn-recover: Recovering log 8 through 8
2018-09-09T12:12:04.290+0100 I STORAGE [initandlisten] WiredTiger message [1536491524:290380][1932:0x7fffa4bb1340], txn-recover: Set global recovery timestamp: 0
2018-09-09T12:12:04.424+0100 I RECOVERY [initandlisten] WiredTiger recoveryTimestamp. Ts: Timestamp(0, 0)
2018-09-09T12:12:04.593+0100 I CONTROL [initandlisten]
2018-09-09T12:12:04.593+0100 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database.
2018-09-09T12:12:04.593+0100 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted.
2018-09-09T12:12:04.593+0100 I CONTROL [initandlisten]
2018-09-09T12:12:04.593+0100 I CONTROL [initandlisten] ** WARNING: This server is bound to localhost.
2018-09-09T12:12:04.593+0100 I CONTROL [initandlisten] ** Remote systems will be unable to connect to this server.
2018-09-09T12:12:04.593+0100 I CONTROL [initandlisten] ** Start the server with --bind_ip <address> to specify which IP
2018-09-09T12:12:04.593+0100 I CONTROL [initandlisten] ** addresses it should serve responses from, or with --bind_ip_all to
2018-09-09T12:12:04.593+0100 I CONTROL [initandlisten] ** bind to all interfaces. If this behavior is desired, start the
2018-09-09T12:12:04.593+0100 I CONTROL [initandlisten] ** server with --bind_ip 127.0.0.1 to disable this warning.
2018-09-09T12:12:04.593+0100 I CONTROL [initandlisten]
2018-09-09T12:12:04.750+0100 I FTDC [initandlisten] Initializing full-time diagnostic data capture with directory '/data/db/diagnostic.data'
2018-09-09T12:12:04.754+0100 I NETWORK [initandlisten] waiting for connections on port 27017
2018-09-09T12:12:12.339+0100 I NETWORK [listener] connection accepted from 127.0.0.1:56872 #1 (1 connection now open)
2018-09-09T12:12:12.346+0100 I NETWORK [conn1] received client metadata from 127.0.0.1:56872 conn1: { driver: { name: "nodejs", version: "3.1.4" }, os: { type: "Darwin", name: "darwin", architecture: "x64", version: "17.4.0" }, platform: "Node.js v8.11.1, LE, mongodb-core: 3.1.3" }
routes/api/users.js
const express = require("express");
const router = express.Router();
const gravatar = require("gravatar");
const bcrypt = require("bcryptjs");
// Load User model
const User = require("../../models/User");
// @route GET api/users/test
// @desc Tests users route
// @access Public
router.get("/test", (req, res) => res.json({ msg: "Users Works" }));
// @route GET api/users/register
// @desc Register user
// @access Public
router.post("/register", (req, res) => {
// function later(delay) {
// return new Promise(function(resolve) {
// setTimeout(resolve, delay);
// });
// }
// later(1000).then(() => {
// console.log("promise worked!");
// res.json({ msg: "promise worked!" });
// });
User.findOne({ email: req.body.email })
.then(user => {
if (user) {
return res.status(400).json({ email: "Email already exists" });
} else {
const avatar = gravatar.url(req.body.email, {
s: "200", // Size
r: "pg", // Rating
d: "mm" // Default
});
const newUser = new User({
name: req.body.name,
email: req.body.email,
avatar,
password: req.body.password
});
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(newUser.password, salt, (err, hash) => {
if (err) throw err;
newUser.password = hash;
newUser
.save()
.then(user => res.json(user))
.catch(err => console.log(err));
});
});
}
})
.catch(err => {
console.log(err);
});
});
module.exports = router;
models/User.js
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
// Create Schema
const UserSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
avatar: {
type: String
},
date: {
type: Date,
default: Date.now
}
});
module.exports = User = mongoose.model("users", UserSchema);
server.js
const express = require("express");
const mongoose = require("Mongoose");
const bodyParser = require("body-parser");
const users = require("./routes/api/users");
const profile = require("./routes/api/profile");
const posts = require("./routes/api/posts");
const app = express();
// Body parser middleware
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// DB Config
const db = require("./config/keys").mongoURI;
// Connect to Mongo DB
mongoose
.connect(db)
.then(() => {
console.log("MongoDB Connected");
})
.catch(err => console.log(err));
app.get("/", (req, res) => res.send("Hello World"));
// Use Routes
app.use("/api/users", users);
app.use("/api/profile", profile);
app.use("/api/posts", posts);
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Server running on port ${port}`));
Upvotes: 2
Views: 1602
Reputation: 311905
The problem is that you're requiring the Mongoose module using different names in server.js ("Mongoose") and models/User.js ("mongoose"). This creates separate instances of the module so the connection made by server.js isn't available to the User
model and the findOne
call is stuck waiting for a connection.
So just change that line in server.js to:
const mongoose = require("mongoose");
Upvotes: 3