Cannot PUT error in Node Express app - javascript

My get and post APIs are working, but for some reason my app.put isn't.
When I hit localhost:3001/contacts/1 as a PUT in PostMan, I don't even see my simple console.log:
app.put('/api/contacts:id', (req, res) => {
console.log('req.params.id', req.params.id);
res.json(contact);
});
app.put
app.put('/api/contacts:id', (req, res) => {
console.log('req.params.id', req.params.id);
res.json(contact);
});
Full server.js code
// Requires ////////////////////////////////////////////////////////////////////
const express = require('express');
const app = express();
const bodyParser = require('body-parser'); // req.body
const cors = require('cors');
const R = require('ramda');
// Variables ///////////////////////////////////////////////////////////////////
const hostname = 'localhost';
const port = 3001;
let contacts = require('./data');
// Logic ///////////////////////////////////////////////////////////////////////
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cors());
app.get('/api/contacts', (req, res) => {
if (!contacts || R.isEmpty(contacts)) returnError(res, 'No Contacts found');
res.json(contacts);
});
app.get('/api/contacts/:id', (req, res) => {
const contact = contacts.filter(contact => contact.id == req.params.id);
if (R.isEmpty(contact)) returnError(res, 'No Contact found');
res.json(R.head(contact));
});
app.post('/api/contacts', (req, res) => {
const contact = {
id: contacts.length + 1,
first_name: req.body.first_name,
last_name: req.body.last_name,
email: req.body.email,
website: req.body.website
}
contacts.push(contact);
res.json(contact);
});
app.put('/api/contacts:id', (req, res) => {
console.log('req.params.id', req.params.id);
// const contact = contacts.filter(contact => {
// return contact.id == req.params.id
// })[0];
// console.log('1 contact', contact);
// const index = contacts.indexOf(contact);
// const keys = Object.keys(req.body);
// keys.forEach(key => {
// contact[key] = req.body[key];
// });
// console.log('2 contact', contact);
// contacts[index] = contact;
// console.log('contacts', contacts);
// res.json(contacts[index]);
res.json(contact);
});
const returnError = (res, msg) => res.status(404).json({ message: msg });
app.listen(port, hostname, () => {
console.log(`server is running at http://${hostname}:${port}`);
});

Looks like a typo in this line:
app.put('/api/contacts:id', (req, res) => {
Add a '/' to read:
app.put('/api/contacts/:id', (req, res) => {

Your URL looks like this:
app.put('/api/contacts:id', (req, res) => {,
But it should be like this:
app.put('/api/contacts/:id', (req, res) => {

Related

Firebase functions can't access my middleware routes

///index.js
const functions = require("firebase-functions");
const express = require("express");
const app = express();
const productRouter = require('./routes/productRoutes');
const globalErrorHandler = require('./controllers/errorController');
const AppError = require('./utils/appError');
// Compressing upcompressed files which is been sent to client such text.
if (process.env.NODE_ENV === 'development') {
app.use(morgan('dev'));
}
// app.use(express.static(path.join(__dirname, 'public')));
app.get('/', (req, res) => {
res.send('Hello World')
});
app.get('/homepage', (req, res) => {
res.send('Hello People of God')
});
app.use('/products', productRouter);
// Handing Unhandled Routes
app.all('*', (req, res, next) => {
next(new AppError(`Can't find ${req.originalUrl} on this server!`, 404));
});
app.use(globalErrorHandler);
exports.app = functions.https.onRequest(app);
///productRoutes.js
const express = require('express');
const {
getProduct,
getAllProduct,
} = require('./../controllers/productController');
const router = express.Router();
router
.route('/')
.get(getAllProduct);
router
.route('/:id')
.get(getProduct);
module.exports = router;
///productController.js
const AppError = require('../utils/appError');
const Product = require('../modals/productModels');
const catchAsync = require('../utils/catchAsync');
// GET SINGLE PRODUCT CONTROLLER
exports.getProduct = catchAsync(async (req, res, next) => {
const product = await Product.findById(req.params.id)
.populate('reviews');
if (!product) {
return next(new AppError('No product found with that ID', 404));
}
res.status(200).json({
status: 'success',
data: {
product
}
});
});
// GET ALL PRODUCT CONTROLLER
exports.getAllProduct = catchAsync(async (req, res, next) => {
const products = await Product.find();
res.status(200).json({
status: 'success',
results: products.length,
data: {
products
}
});
});
///server.js
const mongoose = require('mongoose');
const app = require('./index')
const dotenv = require('dotenv');
// CONNECTING TO MONGODB SERVER
dotenv.config({ path: './config.env' })
const DB = process.env.DATABASE.replace('<PASSWORD>', process.env.DATABASE_PASSWORD);
mongoose.connect(DB, {
useNewUrlParser: true,
safe: true,
strict: false,
useUnifiedTopology: true
}).then(con => console.log('DB connection successful'))
const port = process.env.PORT || 3000;
app.listen(port, () => {
console.log(`App running on port ${port}...`);
});
After running function serve on my terminal i can access the two '/' and 'homepage' app.get which return the res "Hello world" and "Hello people of God" but can't access app.use('/products', productRouter). Its does take some time to run and throw an error "{"code":"ECONNRESET"}" please why is this so.
Am expecting to get my list of products from my mongodb data base.

I have faced CORS policy error .No 'Access-Control-Allow-Origin' header is present on the requested resource [duplicate]

This question already has answers here:
How to enable cors nodejs with express?
(10 answers)
Closed 10 months ago.
I have faced this problem so many time. I require all the middleware in my backend server code but it good for sometimes and then occur, after sometimes it's again running on his own and again cors policy error occur. Please give me a solution . Here is my backend code...
const express = require("express");
const { MongoClient, ServerApiVersion, ObjectId } = require("mongodb");
const cors = require("cors");
const jwt = require("jsonwebtoken");
const port = process.env.PORT || 5000;
require("dotenv").config();
const app = express();
//necessary middleware app.use(cors()); app.use(express.json());
function verifyJWT(req, res, next) {
const authHeader = req.headers.authorization;
if (!authHeader) {
return res.status(401).send({ message: "unauthorized access" });
}
const token = authHeader.split(" ")[1];
jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (err, decoded) => {
if (err) {
return res.status(403).send({ message: "Forbidden access" });
}
console.log("decoded", decoded);
req.decoded = decoded;
next();
});
}
const uri = `mongodb+srv://${process.env.DB_USER}:${process.env.DB_PASS}#cluster0.nfrv0.mongodb.net/myFirstDatabase?retryWrites=true&w=majority`;
console.log(uri);
const client = new MongoClient(uri, {
useNewUrlParser: true,
useUnifiedTopology: true,
serverApi: ServerApiVersion.v1,
});
async function run() {
try {
await client.connect();
const fruitCollection = client.db("fruitsInventory").collection("fruit");
//AUTH API
app.post("/login", async (req, res) => {
const user = req.body;
const accessToken = jwt.sign(user, process.env.ACCESS_TOKEN_SECRET, {
expiresIn: "1d",
});
res.send({ accessToken });
});
//get data
app.get("/inventory", async (req, res) => {
const query = {};
const cursor = fruitCollection.find(query);
const result = await cursor.toArray();
res.send(result);
});
//get inventory id
app.get("/inventory/:id", async (req, res) => {
const id = req.params.id;
const query = { _id: ObjectId(id) };
const result = await fruitCollection.findOne(query);
res.send(result);
});
//get api with filter email
app.get("/myitem", verifyJWT, async (req, res) => {
const decodeEmail = req.decoded.email;
const email = req.query.email;
if (email === decodeEmail) {
const query = { email: email };
const cursor = fruitCollection.find(query);
const result = await cursor.toArray();
res.send(result);
} else {
res.status(403).send({ message: "Forbidden Access" });
}
});
//delete api
app.delete("/myitem/:id", async (req, res) => {
const id = req.params.id;
const query = { _id: ObjectId(id) };
const result = await fruitCollection.deleteOne(query);
res.send(result);
});
//post data
app.post("/inventory", async (req, res) => {
const newItem = req.body;
const result = await fruitCollection.insertOne(newItem);
res.send(result);
});
//update data for quantity
app.put("/inventory/:id", async (req, res) => {
const id = req.params.id;
const updateQuantity = req.body;
const filter = { _id: ObjectId(id) };
const options = { upsert: true };
const updateDoc = {
$set: {
quantity: updateQuantity.quantity,
},
};
const result = await fruitCollection.updateOne(
filter,
updateDoc,
options
);
res.send(result);
});
//delete item
app.delete("/inventory/:id", async (req, res) => {
const id = req.params.id;
const query = { _id: ObjectId(id) };
const result = await fruitCollection.deleteOne(query);
res.send(result);
});
} finally {
}
}
run().catch(console.dir);
app.get("/", (req, res) => {
res.send("fruits server is running");
});
app.listen(port, () => {
console.log("server is connected on port", port);
});
You must set the header of the Axios first because CORS means that you don't have access to origin resource API, so you need to setup the header of Axios first, you can follow this resource CORS
var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors())
app.get('/products/:id', function (req, res, next) {
res.json({msg: 'This is CORS-enabled for all origins!'})
})

login authorization problem, does not pass the token

I am trying to make a login system with authorization, unfortunately the token is not transferred.
const path = require('path');
const express = require('express');
const bodyParser = require('body-parser');
const urlencodedParser = bodyParser.urlencoded({ extended: false });
const mysql = require('mysql');
const validator = require('validator');
const jwt = require('jsonwebtoken');
require('dotenv').config().ACCESS_TOKEN;
const ACCESS_TOKEN = process.env.ACCESS_TOKEN;
const app = express();
app.use(express.json());
const publicDirectoryPath = path.join(__dirname, '../public');
console.log(publicDirectoryPath);
app.use(express.static(publicDirectoryPath));
function generateAccessToken(username) {
return jwt.sign(username, ACCESS_TOKEN, { expiresIn: '1800s' });
}
app.post('/login', urlencodedParser, (req, res) => {
res.get(req.body.username + req.body.password);
const token = generateAccessToken({ username: req.body.username });
res.json(token);
});
function authenticateToken(req, res, next) {
const authHeader = req.headers['authorization']
const token = authHeader && authHeader.split(' ')[1]
console.log(token)
if (token == null) return res.sendStatus(401)
jwt.verify(token, ACCESS_TOKEN, (err, user) => {
console.log(err)
if (err) return res.sendStatus(403)
req.user = user
next()
})
}
app.get('/admin', authenticateToken, (req, res) => {
res.send("admin panel");
})
const port = 3000;
app.listen(port, () => {
console.log(`Server run: http://localhost:${port}`);
})
wants him to be redirected to the admin panel after clicking the login button. However, I am stuck at this stage and do not know what to do next:
enter image description here
You should pass the token to the next route
const path = require('path');
const express = require('express');
const bodyParser = require('body-parser');
const urlencodedParser = bodyParser.urlencoded({ extended: false });
const mysql = require('mysql');
const validator = require('validator');
const jwt = require('jsonwebtoken');
require('dotenv').config().ACCESS_TOKEN;
const ACCESS_TOKEN = process.env.ACCESS_TOKEN;
const app = express();
app.use(express.json());
const publicDirectoryPath = path.join(__dirname, '../public');
console.log(publicDirectoryPath);
app.use(express.static(publicDirectoryPath));
function generateAccessToken(username) {
return jwt.sign(username, 'ACCESS_TOKEN', { expiresIn: '1800s' });
}
app.post('/login', urlencodedParser, (req, res) => {
res.get(req.body.username + req.body.password);
const token = generateAccessToken({ username: req.body.username });
res.redirect(`/admin?token=${token}`);
});
function authenticateToken(req, res, next) {
token = req.query.token;
if (token == null) return res.sendStatus(401);
jwt.verify(token, 'ACCESS_TOKEN', (err, user) => {
console.log(err);
if (err) return res.sendStatus(403);
req.user = user;
next();
});
}
app.get('/admin', authenticateToken, (req, res) => {
res.send('admin panel');
});
const port = 3000;
app.listen(port, () => {
console.log(`Server run: http://localhost:${port}`);
});

Express Middleware: ERROR: TypeError: Converting circular structure to JSON

I'm using the following function as a middleware just to increment the id of a new object being added to my array:
let lions = []
let id = 0
const updateId = function(req, res, next) {
if (!req.body.id) {
id++;
req.body.id = id + '';
}
next();
};
When I post a new lion it will then hit this route:
app.post('/lions', updateId, (req, res) => {
console.log('POST req', req.body)
const lion = req.body;
lions.push(lion)
res.json(req)
})
The POST works and the new lion is created, however I get the following error. Any ideas on how to fix it?
[nodemon] starting node server.js
NODE RUNNING on port: 3000
GET lions: []
ERROR: TypeError: Converting circular structure to JSON
at JSON.stringify ()
at stringify (/Users/leongaban/projects/tutorials/pluralsight/api-design-node/node_modules/express/lib/response.js:1119:12)
server.js
// create a route middleware for POST /lions that will increment and
// add an id to the incoming new lion object on req.body
const express = require('express')
const app = express()
const bodyParser = require('body-parser')
const port = 3000
app.use(express.static('client'))
app.use(bodyParser.urlencoded({ extended: true }))
app.use(bodyParser.json())
let lions = []
let id = 0
const updateId = function(req, res, next) {
if (!req.body.id) {
id++;
req.body.id = id + '';
}
next();
};
app.param('id', (req, res, next, id) => {
let lion = lions.filter((lion => lion.id === id))
if (lion) {
req.lion = lion;
next();
}
else {
console.log('NO LION')
res.send()
}
})
app.get('/lions', (req, res, next) => {
console.log('GET lions:', lions)
res.json(lions)
})
app.get('/lions/:id', (req, res) => {
res.json(req || {})
})
app.post('/lions', updateId, (req, res) => {
console.log('POST req', req.body)
const lion = req.body;
lions.push(lion)
res.json(req)
})
app.put('/lions/:id', (req, res) => {
const paramId = req.params.id
const updated = req.body
if (updated.id) delete updated.id
const oldLion = lions.find((lion => lion.id === paramId))
if (!oldLion) res.send()
const newLion = Object.assign({ id: oldLion.id }, updated)
lions = lions.filter(lion => lion.id !== paramId)
lions.push(newLion)
res.json(newLion)
})
app.delete('/lions/:id', (req, res) => {
lions = lions.filter((lion => lion.id !== req.params.id))
res.json(lions)
})
app.use((err, req, res, next) => {
console.error('ERROR:', err)
})
app.listen(port, () => console.log(`NODE RUNNING on port: ${port}`))
Could be, maybe, because on this line: res.json(req) of the app.post() method, the req object contains an inner property referencing an outer one thus creating a circular reference. Check the structure of that object with console.log() or maybe you can avoid the problem if you return other thing on the response.
– Shidersz
Needed to create a new variable before passing it into the res.json of the put function
app.param('id', (req, res, next, id) => {
let lion = lions.filter((lion => lion.id === id))
if (lion) {
req.lion = lion;
next();
} else {
res.send();
}
})
app.get('/lions', (req, res, next) => {
console.log('GET lions:', lions)
res.json(lions)
})
app.get('/lions/:id', (req, res) => {
console.log('GET lion:', req.lion)
const lion = req.lion // <-- here
res.json(lion || {}) // <-- then here instead of passing req
})

Access req.user to save id to mongoDB

I'm currently having an issue with figuring out how I can access req.user so I can get the logged in users id and save it with the items that they save on the web page. That way when they load the web page they only get their items. The only place I know where I have access to req.user is in my /router/auth.js file. I want to figure out a way to access it in a different router file.
router/auth.js
const express = require('express');
const passport = require('passport');
const bodyParser = require('body-parser');
const jwt = require('jsonwebtoken');
const config = require('../config');
const router = express.Router();
const createAuthToken = function (user) {
return jwt.sign({ user }, config.JWT_SECRET, {
subject: user.username,
expiresIn: config.JWT_EXPIRY,
algorithm: 'HS256'
});
};
const localAuth = passport.authenticate('local', { session: false });
router.use(bodyParser.json());
router.post('/login', localAuth, (req, res) => {
const authToken = createAuthToken(req.user.serialize());
res.json({ authToken });
});
const jwtAuth = passport.authenticate('jwt', { session: false });
router.post('/refresh', jwtAuth, (req, res) => {
const authToken = createAuthToken(req.user);
res.json({ authToken });
});
/router/portfolio.js
router.post('/:id', (req, res) => {
const id = req.params.id;
const { holdings } = req.body;
CryptoPortfolio.findOne({ id }, (err, existingCoin) => {
if (existingCoin === null) {
getCoins(id)
.then(x => x[0])
.then(value =>
CryptoPortfolio.create({
id: value.id,
holdings,
_creator: this is where I want to add req.user.id
}).then(() => value))
.then(newItem => {
res.status(201).json(newItem);
})
.catch(err => {
console.error(err);
res.status(500).json({ message: 'Internal server error' });
});
} else {
const capitalizedId = id.charAt(0).toUpperCase() + id.slice(1);
res.json(`${capitalizedId} already in watchlist`);
}
});
});
You can define global variable and use it using middleware.
app.js
// Global Vars
app.use(function (req, res, next) {
res.locals.user = req.user
next();
});
route.js
router.get('/', function(req, res) {
CryptoPortfolio.find({}, function(err, crypto) {
console.log('CryptoPortfolio : ',crypto);
res.render('view/crypto', {
user : res.locals.user // <= here
});
});
});
I hope it would be helpful :)
I figured out that I wasn't using the code below on any of the necessary routes. Implemented it and I can now access req.user.
const jwtAuth = passport.authenticate('jwt', { session: false });

Categories

Resources