ExpressJS Route hanging and timing out - javascript

I have a simple example that I am following.
For some reason the request always times out, wondering if you have any ideas why this could be happening.
// server.js
// BASE SETUP
// =============================================================================
// call the packages we need
var express = require('express'); // call express
var app = express(); // define our app using express
var bodyParser = require('body-parser');
// configure app to use bodyParser()
// this will let us get the data from a POST
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
var port = process.env.PORT || 8080; // set our port
//load the model
var Bear = require('./models/bear');
// ROUTES FOR OUR API
// =============================================================================
var router = express.Router(); // get an instance of the express Router
// middleware to use for all requests
router.use(function(req, res, next) {
// do logging
console.log('Something is happening.');
next(); // make sure we go to the next routes and don't stop here
});
router.route('/bears')
// create a bear (accessed at POST http://localhost:8080/api/bears)
.post(function(req, res) {
var bear = new Bear(); // create a new instance of the Bear model
bear.name = req.body.name; // set the bears name (comes from the request)
// save the bear and check for errors
bear.save(function(err) {
if (err)
res.send(err);
//res.json({ message: 'Bear created!' });
res.json({ message: 'hooray! welcome to our api!' });
});
});
// test route to make sure everything is working (accessed at GET http://localhost:8080/api)
router.get('/', function(req, res) {
res.json({ message: 'hooray! welcome to our api!' });
});
// more routes for our API will happen here
// REGISTER OUR ROUTES -------------------------------
// all of our routes will be prefixed with /api
app.use('/api', router);
// START THE SERVER
// =============================================================================
app.listen(port);
console.log('Magic happens on port ' + port);
Let me know what you think. Essentially I can do GETS no problem, but when I get to /bears and do a POST x-www-form-urlencoded with a param name 'Klaus' it simply hangs. I can't understand why.
Any suggestions much appreciated.
Many thanks for your help.

Related

Send variables to all routes in expressjs

I have req.session variables that I am setting upon login, like so:
req.session.loggedin = true
req.session.firstname = loginDetails.firstName;
what I want to do is pass this information to ALL routes (I have nearly 60, and don't want to go through all of them and add these in manually), and also every route I have calls the front-end using this:
res.render('page.ejs', {data: rows}), so I would ideally want it to pass it to the front-end pages so I can access them there too. Not sure if this is possible, but worth a shot! thx 4 the help in advance!
You can create a middleware function and add variables to an existing express-session.
app.js
const express = require("express");
const session = require("express-session");
// express app
const app = express();
app.use(express.json());
// init example session with express session
app.use(session({ resave: true, secret: "123456", saveUninitialized: true }));
// use a middleware function
app.use((req, res, next) => {
if (!req.session.initialised) {
// init variables you want to set in req.session
req.session.loggedin = true;
req.session.firstname = "john doe";
}
next();
});
// test api endpoint
app.use("/testroute", require("./routes/api/test"));
// run server
const PORT = process.env.PORT || 8000;
app.listen(PORT, () => console.log(`Server started on port ${PORT}`));
Then you can query your variables like req.session.firstname in any other route in the request object. You can also update it from your routes
test.js
// testroute
const router = express.Router();
router.get("/", async (req, res) => {
// get variables from request object
try {
console.log(req.session.firstname);
console.log(req.session.loggedin);
// this would update the session variable if uncommented
// req.session.firstname = "dagobert"
// console.log(req.session.firstname);
res.status(200).json({ message: `Your firstname is ${req.session.firstname}` });
} catch (error) {
res.status(400).json({ message: error.message });
}
});
module.exports = router;

error when trying to use express in a controller

I've been trying to implement a paymentCtrl to handle the Stripe payments but am unable to get the express to work. When i execute this code i get the following error below. I'm quite new to this and would like to understand why i get this error.
error:
Unknown provider: appProvider <- app <- paymentCtrl
app.js:
angular.module('userApp', ['appRoutes', 'userControllers', 'userServices', 'ngAnimate', 'mainController', 'authServices', 'managementController', 'paymentController'])
.config(function($httpProvider) {
$httpProvider.interceptors.push('AuthInterceptors');
});
payment.html:
<div>
<form action="/charge" method="post">
<script
src="https://checkout.stripe.com/checkout.js"
class="stripe-button"
data-key="pk_test_..."
data-amount="3000"
data-name="walla"
data-description="this is not a dog"
data-locale="auto"
data-currency="gbp"
></script>
</script>
</form>
</div>
paymentCtrl:
angular.module('paymentController', [])
.controller('paymentCtrl', function(app, passport) {
app.post('/charge', function(req, res){
});
});
server.js:
var express = require('express'); // ExperssJS Framework
var app = express(); // Invoke express to variable for use in application
var port = process.env.PORT || 8080; // Set default port or assign a port in enviornment
var morgan = require('morgan'); // Import Morgan Package
var mongoose = require('mongoose'); // HTTP request logger middleware for Node.js
var bodyParser = require('body-parser'); // Node.js body parsing middleware. Parses incoming request bodies in a middleware before your handlers, available under req.body.
var router = express.Router(); // Invoke the Express Router
var appRoutes = require('./app/routes/api')(router); // Import the application end points/API
var path = require('path'); // Import path module
var passport = require('passport'); // Express-compatible authentication middleware for Node.js.
var social = require('./app/passport/passport')(app, passport); // Import passport.js End Points/API
var stripe = require('stripe')('sk_test_...');
app.use(morgan('dev')); // Morgan Middleware
app.use(bodyParser.json()); // Body-parser middleware
app.use(bodyParser.urlencoded({ extended: true })); // For parsing application/x-www-form-urlencoded
app.use(express.static(__dirname + '/public')); // Allow front end to access public folder
app.use('/api', appRoutes); // Assign name to end points (e.g., '/api/management/', '/api/users' ,etc. )
//
// <---------- REPLACE WITH YOUR MONGOOSE CONFIGURATION ---------->
//
mongoose.connect('mongodb://localhost:27017/tutorial', function(err) {
if (err) {
console.log('Not connected to the database: ' + err);
} else {
console.log('Successfully connected to MongoDB');
}
});
// Set Application Static Layout
app.get('*', function(req, res) {
res.sendFile(path.join(__dirname + '/public/app/views/index.html')); // Set index.html as layout
});
// Start Server
app.listen(port, function() {
console.log('Running the server on port ' + port); // Listen on configured port
});
Your angular controller should be injected with $http module, app is undefined in your client side code as client side would not inherit code from your server.
$http module contains .post method along side numerous other methods such as .get .put .delete etc.
angular.module('paymentController', [])
.controller('paymentCtrl', function(app, passport, $http) {
$http.post('/charge', {}, function(req, res){
});
});
The second parameters in the $http.post ({}) is the data you want to transmit to your controller.
Lastly, you need a server method which will retrieve the POST request.
app.post('/charge', function(req, res) {
// Your server endpoint for /charge POST action
// req.body contains passed data.
});
As you're trying to send data using Angular to your server, you'll need to bind the form data to your model, and remove the form or listen to form submit event and make a POST request yourself the way you want to.
As you have not included the whole HTML document, it is hard to see if there are any other errors included, such as missing ng-controller declaration in your document as comments stated.
I assume you followed this Stripe tutorial so all you need to do is:
The code you've written in paymentCtrl should be copied into server.js before app.listen
// Set Application Static Layout
app.get('*', function(req, res) {
res.sendFile(path.join(__dirname + '/public/app/views/index.html')); // Set index.html as layout
});
app.post('/charge', function(req, res){});
// Start Server
app.listen(port, function() {
console.log('Running the server on port ' + port); // Listen on configured port
});
Unknown provider: appProvider <- app <- paymentCtrl
This means that app variable you are trying to inject does not exist in your client side code.

Express.js Handle unmached routes

Fellows I develop a Rest API and I want when a route does not exist to send a custom message instead of an html one that express.js sends by default. As fas as I searched I could not find a way to do that.
I tried to do:
app.all("*",function(req,res){
res.status(404)
res.header("Content Type","application/json")
res.end(JSON.stringify({message:"Route not found"}))
});
But it matches and all already implemented methods. I want only the unmached one to get handled by my app.
Edit 1
For each enndpoint I create a seperate file having the following content: eg. myendpoint.js
module.exports=function(express){
var endpoint="/endpoint"
express.get(endpoint,function(req,res){
res.end("Getting data other message")
}).post(endpoint.function(req,res){
res.end("Getting data other message")
}).all(endpoint,function(req,res){
res.status(501)
res.end("You cannot "+res.method+" to "+endpoint)
})
}
An in my main file I use:
var endpoint=require('myendpoint.js')
var MyEndpointController=endpoint(app)
app.all("*",function(req,res){
res.status(404)
res.header("Content Type","application/json")
res.end(JSON.stringify({message:"Route not found"}))
});
1.Declare all of your routes
2.Define unmatched route request to error respose AT the END.
This you have to set it in the app. (app.use) not in the routes.
Server.js
//Import require modules
var express = require('express');
var bodyParser = require('body-parser');
// define our app using express
var app = express();
// this will help us to read POST data.
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var port = process.env.PORT || 8081;
// instance of express Router
var router = express.Router();
// default route to make sure , it works.
router.get('/', function(req, res) {
res.json({ message: 'hooray! welcome to our api!' });
});
// test route to make sure , it works.
router.get('/test', function(req, res) {
res.json({ message: 'Testing!' });
});
// all our routes will be prefixed with /api
app.use('/api', router);
// this is default in case of unmatched routes
app.use(function(req, res) {
// Invalid request
res.json({
error: {
'name':'Error',
'status':404,
'message':'Invalid Request',
'statusCode':404,
'stack':'http://localhost:8081/'
},
message: 'Testing!'
});
});
// state the server
app.listen(port);
console.log('Server listening on port ' + port);
Please note : I have prefix '/api' in my routes.
Please try http://localhost:8081/api
You will see '{"message":"hooray! welcome to our api!"}'
When you try http://localhost:8081/api4545 - which is not a valid route
You would see the error message.
First you need to define all existing routes then at last you have to define no
route. order is very important
// Defining main template navigations(sample routes)
app.use('/',express.static(__dirname + "/views/index.html"));
app.use('/app',express.static(__dirname + "/views/app.html"));
app.use('/api',express.static(__dirname + "/views/api.html"));
app.use('/uploads',express.static(path.join(__dirname, 'static/uploads')));
//If no route is matched by now, it must be a 404
app.use(function(req, res, next) {
res.status(404);
res.json({status:404,title:"Not Found",msg:"Route not found"});
next();
});
Can't post as comment (reputation is too low ...) but did you define this route after all your other paths ?
The order is really important, you should first define all your routes and then have this one.
on my case for the safetyness of my routes life cycle I used this **/** or */*, *(asterisk) operator stands for all, and here's my example.
app.use('**/**',express.static(path.join(__dirname, './public/not-found/index.html')));

Node, how can I send response headers on a node/express app?

I have a basic server. One of my tests that I need to pass is to send the response header of 200. I added the code for the server as it is now. But not sure how to send response headers. Thanks for any help you may be able to provide!
var express = require('express');
var bodyParser = require('body-parser');
var Users = require('./models/users');
var app = express();
app.use(bodyParser.json());
// YOUR CODE BELOW
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var router = express.Router();
// middleware for all requests:
router.use(function(req, res, next){
console.log('we out here babay!');
// get to the next route and ensures we don't stop here.
next();
})
router.get('/', function(req, res) {
res.json({ message: 'hooray! welcome to our api!' });
});
app.use('/api', router);
// Do not touch this invocation of the `listen` method
app.listen('8888', function () {
console.log('listening on 8888');
});
// Do not touch the exports object
module.exports = app;
Use res.status(CODE) method!
res.status(200).json({ message: 'hooray! welcome to our api!' });
As highlighted in comments by jfriend00, default status code is 200 so any regular response will already be 200 but for other codes like 500 or 404, if your client side is considering it while reading the response, you can use res.status() method.

CORS header not working in MEAN stack application

I am developing an application using the MEAN stack (Node.js, Express, AngularJS, and Mongoose). I have a basic understanding of the two. My API is running on a different port from my frontend, and because of this, I've included the CORS header in my API file. However, Chrome is still giving me this error:
XMLHttpRequest cannot load http://localhost:9000/#/.
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
This is the header I've included in my API:
app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
next();
});
I have no idea where I'm going wrong. If it helps at all, I'm trying to load a user object in order to display information on a profile page. This is the code from my Profile Controller:
angular.module('angTestApp')
.controller('ProfileCtrl', function ($scope, $http) {
$http.get('http://localhost:8080/profile')
.success(function (user) {
$scope.user = user;
console.log(user);
});
});
EDIT
Here's my server.js file if that helps:
// server.js
// BASE SETUP
// =============================================================================
// call the packages we need
var express = require('express'); // call express
var cors = require('cors');
var app = express(); // define our app using express
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
mongoose.connect('mongodb://test:test#novus.modulusmongo.net:27017/a3pemoGa')
var classroom = require('./app/models/classroom');
var article = require('./app/models/article');
var user = require('./app/models/user');
//From Tutorial
var passport = require('passport');
var flash = require('connect-flash');
var morgan = require('morgan');
var cookieParser = require('cookie-parser');
var session = require('express-session');
// configure app to use bodyParser()
// this will let us get the data from a POST
app.use(bodyParser());
app.use(cors());
//app.use(express.static(__dirname + '/public'));
var port = process.env.PORT || 8080; // set our port
// ROUTES FOR OUR API
// =============================================================================
// more routes for our API will happen here
// REGISTER OUR ROUTES -------------------------------
//From tutorial
// set up our express application
require('./app/config/passport')(passport); // pass passport for configuration
app.use(morgan('dev')); // log every request to the console
app.use(cookieParser()); // read cookies (needed for auth)
app.use(bodyParser.json()); // get information from html forms
app.set('view engine', 'ejs'); // set up ejs for templating
app.use(session({ secret: 'ilovescotchscotchyscotchscotch' })); // session secret
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
app.use(flash()); // use connect-flash for flash messages stored in session
require('./app/API/routes')(app, passport);
//require('./app/API/general');
// START THE SERVER
// =============================================================================
app.listen(port);
console.log('Magic happens on port ' + port);
//exports = module.exports = app;
i resolved the cors issue with tricky solution . first create the the route of scrape like this with require "REQUEST" npm
app.get('/scrape', function (req, res) {
console.log("=============================Scrape =========================")
var url = req.body.url;
request(url, function(error, response, html){
if(!error){
res.send(html)
}
});
and in the frontend use like this
$http.get("/scrape", {
params: { "url": "http://localhost:8080/profile" }
});

Categories