I know my problem may seem not very specific, but I'm having problem describing what's happening because I don't understand it :(
So I've written small express app with ssr (for react) and jwt authentication. The SSR part works nice but the rest is crap.....
import 'babel-polyfill';
import express from 'express';
import bodyParser from 'body-parser';
import logger from 'morgan';
import authRouter from './auth/authRouter';
const app = express();
app.use(express.static('public'));
app.use(logger('dev'));
app.use(bodyParser.json({ type: '*/*' }));
app.use(bodyParser.urlencoded({ extended: false }));
//a lot of irrelevant ssr code
authRouter(app);
app.listen(3000, function(err) {
if (err) {
console.log(err);
}
console.log('main server on port 3000');
});
This is my main server file. My first problem is I don't see ANY console.logs from my files. There's nothing in my terminal. That's the reason I can't see how does my requests look like in my app. I'm testing it using postman like that:
And that's the authRouter I'm using above in main server file:
import express from 'express';
import { signup, signin } from '../controllers/authentication';
import { jwtLogin, localLogin } from '../services/passport';
import passport from 'passport';
passport.use(jwtLogin);
passport.use(localLogin);
//if user is auth'd do not create session for him
const requireAuth = passport.authenticate('jwt', { session: false });
const requireSignin = passport.authenticate('local', { session: false });
const authRouter = function(app) {
app.get('/auth', requireAuth, function(req, res) {
res.send({ hi: 'there' });
});
app.post('/auth/signin', requireSignin, signin); // irrelevant right now
app.post('/auth/signup', signup);
};
export default authRouter;
And that's signup function I'm using in router:
const signup = (req, res, next) => {
console.log('reqqqqqqq', req);
const { email, password, passwordCheck } = req.body; //code crashes here
//some code I deleted for everyones convenience
};
Every request I make my app crashes because req.body is undefined. I can't log req because I can't see any logs. I also tried sending back stringified version of my request body but every time i get "TypeError: Converting circular structure to JSON".
I'll be happy to add any information you may need
EDIT:
I'm gonna check that later at home but now I'm thinking there is something wrong with ssr part of my app because I don't even see that 'main server on port 3000' log..... At the same time server responds with right html, js files and routing works well so.....anyway I'm gonna look it up later
Try using util.inspect from node:
const util = require('util');
// usage in your code
const signup = (req, res, next) => {
console.log(util.inspect(req, { showHidden: true, depth: null }));
const { email, password, passwordCheck } = req.body;
...
};
I solved it.....unexpectedly the problem was lying in my package.json file.
My start script looked like this:
"scripts": {
"start": "nodemon build/server.bundle.js | nodemon build/api.bundle.js",
...
}
And because of that I had these weird errors. Only api.bundle.js file was running correctly......
Anyway thanks for your help ;)
Related
Using the Following Stack Express,Vue,SQL,Axios
GET request is working fine in postman as well from Axios
POST request created error in both attached screenshots
To make sure the Backend is working fine I have tried sending the Data directly from
<form action="url" method="POST">
it is Working fine and data is storing in the database
I have Tried few workaround like disabling SSL setting in postman and Played with proxy setting Also having CORS enabled in the backend and tried some Allow content and header things. Nothing worked
Not able to figure out the Problem in the POST Request. Please Help
--Request Error in the browser from Axios ----
Axios Browser Error
-postman Error when doing POST Request---
Postman Error
---Backend Index.js file---
// const express = require("express");
"use strict";
import express from "express";
const app = express();
import cors from "cors";
//listening on this port
app.listen(3000);
app.use(cors()); // to get Data from Other Domains
app.get("/", function (req, res) {
res.send("Application Started");
console.log("Application Started");
});
//Routes
app.use("/product", require("./routes/product"));
---product.js routes files---
import express from "express";
const router = express.Router();
import bodyParser from "body-parser";
//Middleware
router.use(bodyParser.urlencoded({ extended: true })); // To Parse the body data
//Importing Main Controller
import conProduct from "../controllers/ConProduct";
//Defining functions as per Routes
router.post("/add", conProduct.add); //Showing all the products
router.get("/get", conProduct.get); //Showing all the products
//Exporting Router
module.exports = router;
---Controller for Product file ConProducts.js ---
import sqlConfig from "../database/dbConfig";
let sql = sqlConfig.mysql_pool;
exports.add = (req, res) => {
console.log(req.body);
const { name, shortDescription, price, discount } = req.body;
let addQuery =
"INSERT INTO products(name,short_description,price,discount) VALUES('" +
name +
"','" +
shortDescription +
"','" +
price +
"','" +
discount +
"');";
sql.query(addQuery, (err, result) => {
if (err) throw err;
console.log(result);
res.send("product uploaded");
});
};
--Frontend axios Request --
let formData = {
name: this.name,
shortDescription: this.shortDescription,
price: this.price,
discount: this.discount,
};
console.log(formData);
axios
.post("/product/add", formData)
.then((res) => console.log(res))
.catch((error) => console.log(error));
I got the Answer I was missing a middleware app.use(bodyParser.json) in index.js and because of that there was no value going into database and thus, there was a network error.
I realized that, you are sending a PUT request to backend but your API controller receiving POST requests. So, Don't they have to be same type of request ?
Req.body is not accessible in the routes while making a post request. It would be highly appreciative of someone if he/she help me getting through it. Here is screenshot of my microservice.test.js file. Am I missing something?
import request from "supertest";
import mongoose from "mongoose";
import config from "../config/env";
import routes from "../server/routes";
import { parseResponse, doRequest } from "../server/utils/helperFunctions";
const app = express();
app.use("/", routes);
jest.setTimeout(30000);
The code provided doesn't provide much insight, as I would expect all of the handling of the request to be in your route handler. Is the issue that you are unable to access the body when running tests with supertest? Or that it isn't working at all. More information would be very helpful.
If it is a supertest issue, I would recommend checking out the docs for good examples. Here is one I pulled directly from the NPM site where they POST some data with a request body and then verify the response body:
describe('POST /user', function() {
it('user.name should be an case-insensitive match for "john"', function(done) {
request(app)
.post('/user')
.send('name=john') // x-www-form-urlencoded upload
.set('Accept', 'application/json')
.expect(function(res) {
res.body.id = 'some fixed id';
res.body.name = res.body.name.toLowerCase();
})
.expect(200, {
id: 'some fixed id',
name: 'john'
}, done);
});
});
Also, if you are trying to test your server you should probably import your server code instead of creating a new express instance. For example, in your server code you'll have something like this:
server.js
const express = require('express');
const app = express();
app.use('/', ...) // middleware/route config
...
module.exports = app;
Your server would then use this server like this:
index.js
const app = require('./server')
const port = 4000
app.listen({ port }, () => {
const location = `http://localhost:${port}`
logger.info(`🚀 Server ready at ${location}`)
})
module.exports = app
Now that you have structured your code this way, in your test you can import your server as well (so you are testing your actual server, not a new server that you made up):
server.test.js
const app = require('../../../server');
const request = require('supertest')(app);
describe('Server', () => {
it('does a thing', async () => {
const { body } = await request
.post('http://path/to/test')
.send({ data: 'some data' })
.set('Content-Type', 'application/json')
.set('Accept', 'application/json')
.expect(200);
expect(body.thing).toBeTrue();
});
});
expressjs version lower than 4 include body parsing middleware
import bodyParser from 'body-parser';
app.use(bodyParser());
example test
it('.post should work with data', function (done) {
var app = express();
app.use(bodyParser());
app.post('/', function(req, res){
res.send(req.body.name);
});
request(app)
.post('/')
.send({ name: 'tobi' })
.expect('tobi', done);
})
I'm just learning Express/React and I'm trying to get set up with routes and basic database connections. I suspect I'm missing something very simple. I've tried to boil it down to the following.
Backend
server.js:
require('dotenv').config({path: '../.env'});
const mysql = require('mysql');
const express = require('express');
const bodyParser = require('body-parser');
const port = process.env.PORT || 5000;
const app = express();
const router = express.Router();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
const users = require('./routes/api/users');
app.use('/api/users', users);
const events = require('./routes/api/events');
app.use('/api/events', events);
const db = mysql.createConnection({
host: process.env.DB_HOST,
database: process.env.DB_NAME,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD
});
db.connect(function(err) {
if (err) throw err;
console.log('MySQL Connected!');
})
app.listen(port, () => console.log(`Listening on port ${port}`));
/routes/api/events.js:
const express = require('express');
const router = express.Router();
// GET api/events
router.get('/', (req, res) => {
res.send({id: "1", name: "hi"});
});
module.exports = router;
Frontend
App.js:
import React, { Component } from 'react';
import EventList from './components/EventList';
class App extends Component {
render() {
return (
<div className="App">
<EventList/>
</div>)
}
}
export default App;
/components/EventList.js:
import React, { Component } from 'react';
import axios from 'axios';
class EventList extends Component {
constructor() {
super();
this.state = {
events: []
}
}
componentDidMount() {
axios.get('/api/events')
.then(events => {
this.setState({events: events.data})
})
.catch(err => console.log(err))
}
render() {
var events = this.state.events;
return (
<div>
<p>Events:</p>
<ul>
{ events.map(({ id, name }) => (
<li>{name}</li>
))}
</ul>
</div>
)
}
}
export default EventList;
The error I get is http://localhost:3000/api/events 500 (Internal Server Error). What am I missing? I have truly scoured all of the docs I can find, but I'm not quite getting it.
Edit
I haven't changed anything, but now I'm getting a 404 (Not Found) instead. I had been getting a 500 for awhile, so it wasn't a momentary fluke. I'm not sure what could have changed.
Update
It may help to know that the .env variables I'm pointing to are actually for a remote MySQL database (i.e., DB_HOST != localhost, but a remote URL). Eventually, I'd like to connect the GET call on the events route to that db, but since it doesn't work with what I have here I figured my first issue to solve was upstream. As noted in comments, the PORT var I'm loading in is 3306. When I start the server, it says it's listening on 3306 as expected.
I think you are running your server on port 5000 and front on port 3000. if you request events with http://localhost:5000/api/events instead of /api/events, you would get 200 status code with your json data.
// as is
axios.get('/api/events')
// to be
axios.get('http://localhost:5000/api/events')
You could try typing componentDidMount function like this.
componentDidMount = async () =>{
//like this
}
In addition, I would recommend making the GET ALL its own function so you could just invoke in the componentDidMount function. whenever you run another CRUD action it will automatically update your events for you and instead of setting state every time you can invoke the this.getEvents() again to update it that way.
componentDidMount = async () =>{
this.getEvents()
}
Also you need to add this package (npm install cors) its so you can connect your api to your frontend.
Import it like this in your server.js file
const cors = require('cors')
app.use(cors())
You should add a proxy inside package.json in frontend like this.
"proxy": "http://localhost:5000",
Hello and thank you in advance.
We are running our Node.js/Express application in App Engine which serves a React front end as static files. At one point the user is able to redirect to a third-party so that the user can sign in and authorize some of their data which is managed by that third-party. We provide the redirect URI to the third-party as a parameter in the querystring, which is https://www.example.com/api/thirdparty/OAuthCallback.
When the user submits the authorization on the third-party side, they should be redirected to that URI, which is an API endpoint in our application where we process the result, and then in our backend we redirect the user to their dashboard. Instead, the user gets redirected to that URI in the browser.
We know (we think) we are doing the routing correctly because we are able to hit that end point from Postman and simulate the process that way.
The question is, why is this redirection going to the browser and not our backend?
Below you will find our server entry point (index.js) along with the route we expect to hit (thirdparty.js)
index.js:
//index.js
import express from "express";
import thirdparty from "./routes/thirdparty";
import httpsRedirect from "./middlewares/https-redirect";
const app = express();
var httpsPort = app.get('https-port');
app.use(httpsRedirect({httpsPort: httpsPort}));
app.set('trust proxy', true);
app.use(bodyParser.json({limit: '50mb'}));
app.use(bodyParser.urlencoded({limit: '50mb', extended: true}));
app.use(express.static(path.join(__dirname, '../build')));
app.use("/api/thirdparty", thirdparty);
app.get("/*", (req, res, next) => {
console.log('new request from: '+req);
res.sendFile(path.join(__dirname, '../build', 'index.html'));
});
app.listen(8080, ()=>console.log('Listening on port 8080'));
thirdparty.js (route):
// thirdparty.js
import express from "express";
const router = express.Router();
var oauth2 = require('./lib/OAuth2.0')();
router.get('/OAuthCallback', function (req, res) {
console.log("CODE--------------------------- : " + req.query.code);
var params = {
code: req.query.code,
redirect_uri: 'https://www.example.com/api/thirdparty/OAuthCallback'
}
oauth2.authCode.getOAuthToken(params, saveToken);
function saveToken(error, result) {
// do things with the result
res.redirect(process.env.HOST+"/dashboard");
}
});
export default router;
I'm using express 4.16.3 and trying to make sense of why one request to a controller works and a request doesn't.
in my server.js i've got the following. There's no semi-colons because used prettier beforehand.
import express from 'express'
import bodyParser from 'body-parser'
import cors from 'cors'
import PriceCheckerController from './controllers/PriceChecker'
import PersonalLibraryController from './controllers/PersonalLibrary'
const app = express()
app.set('port', process.env.PORT || 5000)
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: true}))
app.use(cors())
// routes definition
app.use('/api/books',PersonalLibraryController) // this does not
app.use('/api/stock-prices', PriceCheckerController) // this works
//
app.listen(app.get('port'), error => {
if (error) {
logger.error(`error fcc-isqa:${error}`)
} else {
logger.info(`fcc-isqa is running on port ${app.get('port')}`)
}
})
export default app
In PriceCheckerController i've implemented it like so.
import 'babel-polyfill' // mocha required
import express from 'express'
import logger from '../logger'
const PriceCheckerController = express.Router()
PriceCheckerController.use((req, res, next) => {
logger.info(
`date=>${new Date()}\n method=>${req.method}nsender:${req.ip}`
)
})
PriceCheckerController.get('/', async (req, res) => {
return res.status(200).json({message:'soon'})
})
export default PriceCheckerController
In PersonalLibraryController i've implemented it like so
import 'babel-polyfill'
import express from 'express'
import logger from '../logger'
const PersonalLibraryController = express.Router()
PersonalLibraryController.use((req,res,next)=>{
logger.info(
`library date=>${
new Date()}method=>${req.method}url=>${req.baseUrl}${req.path}`
)
})
PersonalLibraryController.route('/test')
.get(async (req, res) => {
return res.status(200).json({message: 'get soon'})
})
.post(async (req,res)=>{
return res.status(200).json({message: 'post soon'})
})
export default PersonalLibraryController
A request to /api/stock-prices returns ok with message soon.
A request to /api/books/test is logged by the middleware but a response is not sent back. It eventually gives a timeout
Can anyone give me any insights/ help in understanding what is the problem and how to fix it?
Thanks in advance.
Your middleware functions need to call next() to carry on the route execution.
e.g
PriceCheckerController.use((req, res, next) => {
logger.info(
`date=>${new Date()}\n method=>${req.method}nsender:${req.ip}`
)
next();
})
https://expressjs.com/en/guide/using-middleware.html
"If the current middleware function does not end the request-response cycle, it must call next() to pass control to the next middleware function. Otherwise, the request will be left hanging."