Reference error is not defined on application - javascript

When trying to submit data on a form, the webserver is giving me an error saying Reference error: Item is not defined, but based on my code, everything looks okay to me. Is there anything that stands out to you in my code that might cause this?
I was playing around with the Const, but I'm not sure if that's where the problem lies.
Here's my Javascript file:
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
//specify where to find the schema
const Items = require('./models/item')
// connect and display the status
mongoose.connect('mongodb://localhost:27017/items', { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => { console.log("connected"); })
.catch(() => { console.log("error connecting"); });
// use the following code on any request that matches the specified mount path
app.use((req, res, next) => {
console.log('This line is always called');
res.setHeader('Access-Control-Allow-Origin', '*'); //can connect from any host
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, OPTIONS'); //allowable methods
res.setHeader('Access-Control-Allow-Headers', 'Origin, Content-Type, Accept');
next();
});
app.get('/items', (req, res, next) => {
//call mongoose method find (MongoDB db.Items.find())
Items.find()
//if data is returned, send data as a response
.then(data => res.status(200).json(data))
//if error, send internal server error
.catch(err => {
console.log('Error: ${err}');
res.status(500).json(err);
});
});
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
// serve incoming post requests to /items
app.post('/items', (req, res, next) => {
// create a new item variable and save request’s fields
const Items = new items ({
itemName: req.body.itemName,
servings: req.body.servings
});
//send the document to the database
Items.save()
//in case of success
.then(() => { console.log('Success');})
//if error
.catch(err => {console.log('Error:' + err);});
});
//to use this middleware in other parts of the application
module.exports=app;

app.post('/items', (req, res, next) => {
// Items already defined
const items = new Items({
itemName: req.body.itemName,
servings: req.body.servings
});
items.save()
//in case of success
.then(() => { console.log('Success');})
//if error
.catch(err => {console.log('Error:' + err);});
});
Items constant is already declared, and you trying to re-declare it

Related

Stripe & Node.js - "Cannot POST /create-checkout-session"

I'm trying to follow the Stripe Checkout subscription instructions:
https://stripe.com/docs/billing/subscriptions/build-subscriptions?ui=checkout
When I submit the form, over localhost I get "Cannot POST /create-checkout-session" (404 in network tab), and if I run from my production server, it just opens /create-checkout-session as a new (blank) Vue page. I have tried changing the form action to https://mydomain.xyz/create-checkout-session, but it didn't work.
Subscribe.vue
<form action="/create-checkout-session" method="POST">
<input type="hidden" name="priceId" value="[removed for Stack Overflow]" />
<button type="submit">Checkout</button>
</form>
I don't know if something is interfering with the endpoint, so I've copied my entire app.js file:
app.js
let express = require('express'),
cors = require('cors'),
mongoose = require('mongoose'),
database = require('./database'),
bodyParser = require('body-parser');
// Set your secret key. Remember to switch to your live secret key in production.
// See your keys here: https://dashboard.stripe.com/apikeys
const stripe = require('stripe')('[removed for StackOverflow]');
//connect mongoDB
mongoose.Promise = global.Promise;
mongoose.connect(database.db, {
useNewUrlParser: true,
useUnifiedTopology: true
}).then(() => {
console.log("Database connected")
},
error => {
console.log("Database couldn't be connected to: " + error);
}
)
const cryptoEndPoint = require('../backend/routes/crypto.route')
const app = express();
app.use(decodeIDToken);
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(cors())
//API
app.use('/api', cryptoEndPoint)
app.post("/create-checkout-session", async (req, res) => {
console.log("can't even get anything to console log, only get createError is not defined");
const { priceId } = req.body;
// Create new Checkout Session for the order
// Other optional params include:
// [billing_address_collection] - to display billing address details on the page
// [customer] - if you have an existing Stripe Customer ID
// [customer_email] - lets you prefill the email input in the form
// [automatic_tax] - to automatically calculate sales tax, VAT and GST in the checkout page
// For full details see https://stripe.com/docs/api/checkout/sessions/create
try {
const session = await stripe.checkout.sessions.create({
mode: 'subscription',
line_items: [
{
price: priceId,
// For metered billing, do not pass quantity
quantity: 1,
},
],
// {CHECKOUT_SESSION_ID} is a string literal; do not change it!
// the actual Session ID is returned in the query parameter when your customer
// is redirected to the success page.
success_url: 'https://mydomain.xyz/thankyou?session_id={CHECKOUT_SESSION_ID}',
cancel_url: 'https://mydomain.xyz/thankyou',
});
return res.redirect(303, session.url);
} catch (e) {
res.status(400);
return res.send({
error: {
message: e.message,
}
});
}
});
//create port
const port = process.env.PORT || 4000;
const server = app.listen(port, () => {
console.log('Connected to port ' + port);
})
//Find 404
app.use((req, res, next) => {
next(createError(404));
})
//error handler
app.use(function (err, req, res, next) {
console.log(err.message);
if (!err.statusCode) err.statusCode = 500;
res.status(err.statusCode).send(err.message);
})
/**
* Decodes the JSON Web Token sent via the frontend app
* Makes the currentUser (firebase) data available on the body.
*/
async function decodeIDToken(req, res, next) {
if (req.headers?.authorization?.startsWith('Bearer ')) {
const idToken = req.headers.authorization.split('Bearer ')[1];
// console.log(idToken);
try {
const decodedToken = await admin.auth().verifyIdToken(idToken);
// console.log("one");
req['currentUser'] = decodedToken;
// console.log("two");
} catch (err) {
console.log("error: " + err);
}
}
next();
}
app.post("/webhook", async (req, res) => {
let data;
let eventType;
// Check if webhook signing is configured.
const webhookSecret = '[removed for Stack Overflow]'
if (webhookSecret) {
// Retrieve the event by verifying the signature using the raw body and secret.
let event;
let signature = req.headers["stripe-signature"];
try {
event = stripe.webhooks.constructEvent(
req.body,
signature,
webhookSecret
);
} catch (err) {
console.log(`⚠️ Webhook signature verification failed.`);
return res.sendStatus(400);
}
// Extract the object from the event.
data = event.data;
eventType = event.type;
} else {
// Webhook signing is recommended, but if the secret is not configured in `config.js`,
// retrieve the event data directly from the request body.
data = req.body.data;
eventType = req.body.type;
}
switch (eventType) {
case 'checkout.session.completed':
//...
break;
case 'invoice.paid':
//...
break;
case 'invoice.payment_failed':
//...
break;
default:
// Unhandled event type
}
res.sendStatus(200);
});
Does anyone know what is going wrong?
I added this to my app.js file, and it's working:
var allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', "*");
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
}
app.use(allowCrossDomain);

Having issues with javascript compiling

I have an application Javascript file that is showing an error in the console section of VS Studio Code, it keeps saying: app.js: The parser expected to find a '}' to match the '{' token here. and the console will not compile.
Based on my code, would you be able to tell me where I need to close in my braces? I think I might be confused.
Here is my app.js code:
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
//specify where to find the schema
const Item = require('./models/item')
// connect and display the status
mongoose.connect('mongodb://localhost:27017/items', { useNewUrlParser: true })
.then(() => { console.log("connected"); })
.catch(() => { console.log("error connecting"); });
// use the following code on any request that matches the specified mount path
app.use((req, res, next) => {
console.log('This line is always called');
res.setHeader('Access-Control-Allow-Origin', '*'); //can connect from any host
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, OPTIONS'); //allowable methods
res.setHeader('Access-Control-Allow-Headers', 'Origin, Content-Type, Accept');
next();
});
app.get('/items', (req, res, next) => {
//call mongoose method find (MongoDB db.Students.find())
Item.find()
//if data is returned, send data as a response
.then(data => res.status(200).json(data))
//if error, send internal server error
.catch(err => {
console.log('Error: ${err}');
res.status(500).json(err);
});
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
// serve incoming post requests to /items
app.post('/items', (req, res, next) => {
const items = req.body;
console.log(items.itemName + " " + items.servings);
//sent an acknowledgment back to caller
res.status(201).json('Post successful');
});
//to use this middleware in other parts of the application
module.exports=app;
Your app.get('/items' function is not closed. Try this.
app.get('/items', (req, res, next) => {
//call mongoose method find (MongoDB db.Students.find())
Item.find()
//if data is returned, send data as a response
.then(data => res.status(200).json(data))
//if error, send internal server error
.catch(err => {
console.log('Error: ${err}');
res.status(500).json(err);
});
});
But in the future, please just use an IDE of some sorts. Even just dumping your code into JSFiddle will highlight this for you.

Fetch method put with React.js and Node server

I want to update my data in my MySQL database. I have React front-end and I'm using node server as back-end. I am getting nothing with body when I try to update data with fetch put method. Why is that?
Why does "body" in fetch method with JSON.stringify(req.body) give me an empty object server-side?
React code(button click event):
handlePrioDown(a) {
sessionStorage["id"] = a["id"];
sessionStorage["priority"] = a["priority"];
fetch('http://localhost:3001/TeacherPri/'+a["id"], {
method: 'PUT',
body: JSON.stringify({priority: a["priority"]+1})
})
}
Node (server.js):
//CORS middleware
var allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
}
app.use( bodyParser.json())
app.use(bodyParser.urlencoded({
extended: true
}))
app.use(allowCrossDomain)
app.use(express.json())
app.route("/TeacherPri/:id")
.put(controller.changePriority)
Node (controller.js):
changePriority: (req ,res) => {
let v = req.body;
let key = req.params.id;
console.log(JSON.stringify(v) + " ::::: id="+key)
CONN.query('UPDATE teacher SET priority=? WHERE id=?', [v.priority, key],
(err, results, fields) => {
if(err) {
console.log(err)
res.json(err)
} else {
console.log("Done")
res.statusCode = 204
res.send();
}
})
}
I'm excpecting that I get something like { priority: 4 } as req.body object on server side. I get empty object atm.

Axios data is breaking the request

I have an express API and a ReactJs front-end. I try to make a POST call from my front-end directly to the local API.
For this I'm using axios.
The request is working fine when I set the parameters directly inside the query string but is always getting on timeout if I try to add the parameters through the data attribute of the axios.post() method.
Working
axios.post(`http://localhost:5001/site/authenticate?username=demo&password=demo`)
Not working
const payload = {
"username":"mh",
"password":"mh"
}
axios.post(`http://localhost:5001/site/authenticate`, payload)
My express server:
const express = require('express');
const bodyParser = require('body-parser');
const morgan = require('morgan');
const jwt = require('jsonwebtoken'); // used to create, sign, and verify tokens
var cors = require('cors');
const app = express();
const port = process.env.API_PORT || 5001;
app.use(cors());
app.set('secret', process.env.API_SECRET);
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(morgan('dev'));
app.use((req, res, next) => {
let data = '';
req.setEncoding('utf8');
req.on('data', (chunk) => {
data += chunk;
});
req.on('end', () => {
req.rawBody = data;
next();
});
});
// Allow CORS
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
// SITE ROUTES -------------------
const siteRoutes = express.Router();
siteRoutes.post('/authenticate', function(req, res) {
console.log('auth');
getDocument(usersBucket, req.query.username)
.then((doc) => {
console.log("Authentification... TODO");
// return the information including token as JSON
res.json({
success: true,
status: 200,
token: token
});
})
.catch(() => {
res.status(401).json({ success: false, message: 'Authentification failed. User not found.' });
});
});
// route middleware to verify a token
siteRoutes.use(function(req, res, next) {
const token = req.body.token || req.query.token || req.headers['x-access-token'];
if (token) {
// verifies secret and checks exp
jwt.verify(token, app.get('secret'), function(err, decoded) {
if (err) {
return res.json({ success: false, message: 'Failed to authenticate token.', status: 401 });
} else {
req.decoded = decoded;
next();
}
});
} else {
return res.status(403).send({
success: false,
message: 'No token provided.'
});
}
});
siteRoutes.get('/', function(req, res) {
res.json({ message: 'Welcome!' });
});
app.use('/site', siteRoutes);
app.listen(port, () => {
logger.log(`Express server listening on port ${port}`);
});
Any idea? Thanks.
Update
I replaced my route just to see if I got in or not (without worrying about parameters):
siteRoutes.post('/authenticate', function(req, res) {
console.log("go in");
res.json({
success: true,
status: 200,
});
});
But my console.log is not showing hen I use the payload (it is when I do not).
You should access the payload data via request.body, not the request.query:
// SITE ROUTES -------------------
const siteRoutes = express.Router();
siteRoutes.post('/authenticate', function(req, res) {
console.log('auth');
getDocument(usersBucket, req.body.username) // <------- HERE
.then((doc) => {
console.log("Authentification... TODO");
// return the information including token as JSON
res.json({
success: true,
status: 200,
token: token
});
})
.catch(() => {
res.status(401).json({ success: false, message: 'Authentification failed. User not found.' });
});
});
request.query are the parameters passed in the URL, like:
protocol://hostname:port/path/to.route?query_param_0=value_0&query_param_1=value_1
on your express endpoint request.query will be:
{
query_param_0: value_0,
query_param_1: value_1
}
while sending the payload, with the second argument in axios.post(url, payload):
axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
})
on your express endpoint request.body will be:
{
firstName: 'Fred',
lastName: 'Flintstone'
}
when you use app.use(bodyParser.json()); (and you do).
You are using “getDocument(usersBucket, req.query.username)”
This means you express route is expecting username as a request param. That’s why it’s working when you use “?username=xx”
Instead try to get it from json body of request.
“req.body.username”
Also you should consider validating the request body or param as required.

Capturing response body in Express Middleware

I am trying to write a small API logger as an Express middleware. The logger collects various pieces of information from the req and res, then saves a JSON file to disk that can be read later.
This is my current function to store the logs.
function store(req, res, next) {
init();
const log = {
request_url: req.hostname,
request_body: req.body,
request_method: req.method,
request_headers: req.headers,
api_endpoint: req.baseUrl,
timestamp: moment().format('x')
};
res.on('finish', () => {
log.response_body = res.body;
log.response_status = res.statusCode;
global.enoch_logs.push(log);
fs.writeFile(`./logs/${ moment().format('x') }.json`, JSON.stringify(log), (err) => (err) ? console.log(err) : null);
});
next();
}
The problem is that res.body is always empty. I have tried a few different methods to capture the response body but nothing seems to work.
Where am I going wrong?

Categories