Cannot GET /api/signup - Using Postman and mongodb - node.js

I am very new to mongoose and I made one signup api and while testing it using POSTMAN I'm getting these weird error as well when I refresh my http://localhost:8000/api/signup I get a message saying "Cannot GET /api/signup" and in my postman post request I am seeing an error message that says "Cannot POST /api/signup".
How would I get rid of these messages that are being displayed?
I am following a tutorial so I tried copying and pasting the code from the GitHub to make sure everything was perfect but I was still seeing these error messages.
My app.js file is:
const express = require("express");
const mongoose = require("mongoose");
const morgan = require("morgan");
const bodyParser = require("body-parser");
const cookieParser = require("cookie-parser");
require("dotenv").config();
// import routes
const userRoutes = require("./routes/user");
// app
const app = express();
// db
mongoose
.connect(process.env.DATABASE, {
useNewUrlParser: true,
useCreateIndex: true
})
.then(() => console.log("DB Connected"));
// middlewares
app.use(morgan("dev"));
app.use(bodyParser.json());
app.use(cookieParser());
// routes middleware
app.use('api', userRoutes);
const port = process.env.PORT || 8000;
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
my routes/users.js file is:
const express = require("express");
const router = express.Router();
const { signup } = require("../controllers/user");
router.post("/signup", signup);
module.exports = router;
my controllers/users.js is:
const User = require("../models/user");
exports.signup = (req, res) => {
console.log("req.body", req.body);
const user = new User(req.body);
user.save((err, user) => {
if (err) {
return res.status(400).json({
error
});
}
res.json({
user
});
});
};
I am hoping to see a response in my browser that does not display an image that image that says Cannot GET api/signup and I am hoping that Postman is able to return data from my api

It means there is no corresponding router setting to /api/signup
I think router.post("/signup", signup); should be router.post("/api/signup", signup);
This should work fine on PostMan.
But the browser url is a get request, so the request would still fail. You will need to send the post request by javascript then.
For example, something like :
fetch('/api/signup', {
method: 'POST',
body: 'signup data here'
})
.then(response => response.json());
Please let me know if the error still exist.

There is a minor bug
app.use('api', userRoutes);
change to
app.use('/api', userRoutes);

My issue was that when I installed mongoDB locally I had not properly installed it and was not using a /data/db folder. I was able to fully uninstall my older version of mongoDB and reinstall everything following this youtube tutorial: https://www.youtube.com/watch?v=MIByvzueqHQ

Related

Nodejs - TypeError: res.statusCode is not a function

There are obviously duplicate questions but the answers didn't help me. Either there is something fundamental that I just don't understand yet as a beginner in nodeJS and Express or something weird is happening.
I have two Express routes, the first one works perfectly fine. But as soon as I started working on the second one I immediately encountered the problem when trying to use 'res' to send back a HTTP status code.
server.js (with everything unrelated redacted):
const express = require('express')
const session = require('express-session')
const MySQLStore = require('express-mysql-session')(session)
const db = require('./database')
const route1 = require('./routes/route1')
const route2 = require('./routes/route2')
const sessionStore = new MySQLStore({}, db)
const app = express()
app.use(express.json())
app.use(session({
// session settings
}))
// Routes
app.use('/api/route1', route1)
app.use('/api/route2', route2)
app.listen(process.env.PORT || 8000)
route1.js (with everything unrelated redacted):
const express = require('express')
const db = require('../database')
const router = express.Router()
// Middleware
function validateData(req, res, next) {...}
async function validateUser(req, res, next) {...}
// POST data to db
router.post('/', validateData, validateUser, async (req, res) => {
try {
const results = await db.query(
// Query the database
)
} catch(err) {
// Handle error
}
res.status(200).end()
})
module.exports = router
route2.js - where the error happens (with everything unrelated redacted):
const express = require('express')
const db = require('../database')
const router = express.Router()
router.get('/', (req, res) => {
res.statusCode(200).end() // TypeError: res.statusCode is not a function
})
module.exports = router
It says it correctly.
res.statusCode is not a function, it is Node.js native variable: https://nodejs.org/api/http.html#responsestatuscode
Express have function res.status(statusCode), i.e. res.status(200);: https://expressjs.com/en/api.html#res.status

Mongoose/Express Get all subdocuments api

So I feel foolish for asking this, and I know there are a ton of related posts on this, but I cannot find anything to work. I'm guessing that it has to do with the index.js since Postman is saying it cannot even connect to the route. I have 2 routes, and the clientRoutes works just fine, postman returns and it shows up on my frontend. However, making any call to the contractRoutes gets me nothing.
I'm trying to pull all 'contracts' subdocs for a single client. I'm new to Express/Mongoose and I'm guessing that I've missed something totally obvious.
index.js
const express = require("express")
const mongoose = require("mongoose")
const cors = require('cors')
const clientRoutes = require("./routes/clientRoutes")
const contractRoutes = require("./routes/contractRoutes")
const bodyParser = require('body-parser');
mongoose
.connect("mongodb+srv://admin:oneterra#cluster0.0cajn.mongodb.net/Octotest?retryWrites=true&w=majority", { useNewUrlParser: true })
.then(() => {
const app = express()
app.use(express.json())
app.use(cors())
app.use(bodyParser.json());
app.use("/api", clientRoutes)
app.use("/api", contractRoutes)
app.listen(5000, () => {
console.log("Server has started")
})
})
client model
const mongoose = require("mongoose")
const schema = mongoose.Schema({
clientId: Number,
firstName: String,
lastName: String,
phone: String,
contracts: [{
contractId: Number,
authNumber: String,
contType: String,
contHours: Number,
contStartDate: Date,
contEndDate: Date
}],
})
module.exports = mongoose.model("Client", schema)
clientRoutes - which works as expected
const express = require("express")
const Client = require("../models/Client.js")
const router = express.Router()
//Client routes
router.get("/clients", async (req, res) => {
const clients = await Client.find()
res.send(clients)
})
router.get("/clients/:clientId", async (req, res) => {
try {
const client = await Client.findOne({ clientId: req.params.clientId })
res.send(client)
} catch {
res.status(404)
res.send({ error: "Client not found"})
}
})
contractRoutes which only brings the error "Cannot GET /api/clients/1/contracts" (1 being the clientId, which has contracts in the db). On clientRoutes, from the first tutorial I used, I did not put '' around ({ clientId : req.params.clientId). In the code below I have it there when I was trying to figure this out, but I get the same result, and again seems to show I'm missing something at the top level.
const express = require("express")
const Client = require("../models/Client")
const router = express.Router()
try{
const client = await Client.findOne({ 'clientId': req.params.clientId })
const contracts = client.contracts;
res.send(contracts)
} catch {
res.status(404)
res.send({error: "Contracts not found"})
}
console.log(contracts)
I've tried using populate
Client.findOne({ 'clientId': req.params.clientId })
.populate('contracts')
.exec(
function(err, client) {
if (err) res.status(500).send(err);
res.json(client.contracts);
}
);
and even if I copy the exact same route for a single client from clientRoutes, but with the contracts endpoint, I get the same error as above
const express = require("express")
const Client = require("../models/Client")
const router = express.Router()
//Client routes
router.get("/clients/:clientId/contracts", async (req, res) => {
try {
const client = await Client.findOne({ clientId: req.params.clientId })
res.send(client)
} catch {
res.status(404)
res.send({ error: "Client not found"})
}
})
Any help is greatly appreciated, I've spent hours running in circles on this and trying every type of different way to make the call. But in dialing it down to even using the same route from clientRoutes but with the contracts endpoint and getting the error, I'm assuming it has to due with the index.js server connection.
So in case anyone comes across this with the same issue, as I put in the comment, express wasn't accepting the 2nd route starting with the same path.
By changing
app.use("/api", clientRoutes)
app.use("/api", contractRoutes)
to
app.use("/api", clientRoutes)
app.use("/api/clients", contractRoutes)
then the route worked fine. I did not see anything in the express docs saying that no path can be designated as the same, but making the change made it work, so there's that.

react axios cros body empty

Working on my first MERN app. When I'm trying to call my backend api, it seems that the body content is lost. But it works correctly using Postman. So I guess I have something wrong with my CORS.
Bellow my Frontend and Backend code:
Frontend - login.jsx
import axios from 'axios';
...
axios.get(process.env.REACT_APP_API_URL+'/auth/login'
, {username: 'demo', password: '1234567'}
).then(user => {
console.log(user);
}).catch(error =>{
console.log(error);
});
Backend - index.js
const express = require('express');
const bodyParses = require('body-parser');
const cors = require('cors');
const authRoute = require('./routes/auth');
const app = express();
app.use(bodyParses.json());
app.use(bodyParses.urlencoded({ extended: true }));
app.use(cors());
app.use('/api/auth', authRoute);
...
Backend - auth.js
const rooter = require('express').Router();
rooter.get('/login', async (req, res) => {
console.log('*** req.body:', req.body);
...
}
I got this message in the browser console:
GET http://localhost:5000/api/auth/login 401 (Unauthorized) xhr.js:210
And on the backend side I got this
*** req.body: {}
Any help would be appreciated.
GET requests with axios don’t support a body, change it to a POST:
rooter.post('/login', async (req, res) => {
console.log('*** req.body:', req.body);
axios.post(process.env.REACT_APP_API_URL+'/auth/login'

HOW DO I FIX "CANNOT GET" USING NODEJS MONGODB

I m testing a simple Get api with postman, but i am getting "cannot GET".
server.js (in the root folder)
```const express = require('express');
const mongoose = require('mongoose');
const items = require('./routes/api/items');
const app = express();
//body Parser middleware
app.use(express.json());
//Db config
const db = require('./config/keys').mongoURI;
//const db = "mongodb+srv://gkmm:123123123#cluster0-bo4ln.mongodb.net/test?retryWrites=true&w=majority"
//Connect to mongo
mongoose
.connect(db, { useNewUrlParser:true, useUnifiedTopology: true})
.then(() => console.log('MongoDB Connected...'))
.catch(err => console.log(err));
const port = process.env.PORT || 4000;
app.listen(port, () => console.log(`Server started on port ${port}`));
//Use routes
app.use('./routes/api/items.js', items);```
routes(root folder)/api/items.js
```const express = require('express')
const router = express.Router();
//Item Model
const Item = require('../../models/Item')
//#route GET api/items
//#des Get AAll Items
//access public
router.get('/', (req, res) => {
Item.find()
.sort({ date: -1})
.then(items => res.json(items));
});
module.exports = router; ```
Running into this error while trying to test my API, i checked my paths are correct, my database is connected. but i have no idea why is it returning 404 not found.
After looking through your code, # the line which you ask app to use your routes
//Use routes
/* You are telling the route to go through e.g. <yoururl>/./routes/api/items.js/
in order to reach your GET in items.js
*/
app.use('./routes/api/items.js', items);```
To resolve this issue you can edit your app.use to
app.use('/test', items) // test is just an example, you can change it to other keywords
Then to access your items GET route use "/test/"
Shouldn't app.use('./routes/api/items.js', items); be app.use('/api/items', items); ?

axios first request succeeds second request fails

i have a simple node node express server in which i get data from an api,it works fine on the first request but fails when i try to make a second request
const express=require("express");
const axios =require("axios");
const cors = require('cors');
const app=express();
app.use(cors());
app.get("/devices",(req,res)=>{
axios.get(
'http://ipaddress/api/reports',
).then((response) => {
res.status(200);
res.json(response.data);
}).catch((error) => {
res.status(400)
res.send("error")
});
});
app.listen(3002,()=>{
console.log("started on port 3002");
});
The problem i found here is you have initialize the server in your get route. The app.listen.. code should be outside the get route implementation. I doubt if your code even runs for the first time. Change your code like:
const express = require("express");
const axios = require("axios");
const cors = require('cors');
const app = express();
app.use(cors());
app.get("/devices", (req,res) => {
axios.get(
'http://ipaddress/api/reports',
).then((response) => {
res.status(200).json(response.data);
}).catch((error) => {
res.status(400).send("error")
});
});
app.listen(3002,() => {
console.log("started on port 3002");
});
Hope this helps :)

Resources