app.get is not a function in express.js - node.js

I am actually not able to figure it out that why in index.js file in below code snippet is throwing me an error : app.get is not a function.
Please help me out..
//here is my app.js file
const express = require('express');
const app = express();
const helpers = require('./helpers');
const routes = require('./index')
app.use((req, res, next) => {
app.locals.h = helpers;
next();
});
app.use('/', routes);
app.set('views',(__dirname));
app.set('view engine', 'pug');
app.listen(3000,()=>console.log('port 3000'));
module.exports = app;
//here is my index.js file
const app = require('./app')
app.get('/',(req,res) => {
res.render('template');
})
module.exports = router;
//helpers.js
exports.title = "NODEjs";
//template.pug
doctype html
html
head
title=`${h.title}`
body
h1 myHeading #{h.title}

You have a circular dependency loop and rather than create an infinite loop, the require() subsystem detects that and fails to load your module.
In app.js, you load index.js. In index.js, you load app.js. Circular dependency loop.
There are two separate techniques that can be used to solve your particular problem. You appear to be using about some of one technique and some of another and that creates your problem.
A classic way to define new routes in a separate file is to just have that file create and export its own router. It then assigns the routes to the router (not to app) and thus that other file never needs the app object at all. Because you show module.exports = router, it appears you have part of that technique, but only part of it.
Here's how the code would work to do it that way:
// app.js
const express = require('express');
const app = express();
const helpers = require('./helpers');
app.use((req, res, next) => {
app.locals.h = helpers;
next();
});
// hook in routes from the index.js router
app.use('/', require('./index'));
app.set('views',(__dirname));
app.set('view engine', 'pug');
app.listen(3000,()=>console.log('port 3000'));
// index.js
const router = require('express').Router();
router.get('/',(req,res) => {
res.render('template');
});
module.exports = router;
You could also pass app to index.js when you load it rather than having it try to import app. This also solves the circular dependency issue.
const express = require('express');
const app = express();
const helpers = require('./helpers');
// pass app here so it can register routes
require('./index')(app);
app.use((req, res, next) => {
app.locals.h = helpers;
next();
});
app.use('/', routes);
app.set('views',(__dirname));
app.set('view engine', 'pug');
app.listen(3000,()=>console.log('port 3000'));
Change index.js to export a module constructor which you call and pass app to:
module.exports = function(app) {
app.get('/',(req,res) => {
res.render('template');
})
}

Add parenthesis on the first line :
const express = require('express')();

The first answer should be accepted.
This is happening only due to the circular dependencies in this case.

Related

Node js: getting an error Cannot GET /route when i use get method

When I use the "use" method my code works fine, but when I use the "get" it gives an error: "Cannot GET /route1".
My Code:
const express = require('express');
const app = express();
const expbs = require('express-handlebars');
const path = require('path');
const routes = require('./routes/handlers');
app.use(express.static('public'));
const hbs = expbs.create({
defaultLayout: 'main',
layoutsDir: path.join(__dirname, 'views/mainLayout'),
partialsDir: path.join(__dirname, 'views/pieces'),
});
app.engine('handlebars', hbs.engine);
app.set('view engine', 'handlebars');
app.get('/route1', routes);
app.listen(8080, () => {
console.log('Server is starting at port ', 8080);
});
I am new to node js, please tell me can i define routes with "get" method.
I believe your routes/handlers.js look something like this
var express = require('express');
var router = express.Router();
function greetUser(req, res){
res.send("Welcome dear user");
}
router.get("/", greetUser);
router.post("/", (req, res)=>{ res.send("user registered") });
module.exports = router
The problem here is this last line, this router object which is being exported works fine for app.use middleware, while .get or .post expects 2nd parameter to be a function
If you export this greetUser function from your router as well or receive this function from anywhere, this should start functioning well. Practically it would be
app.get("/route1", (req, res)=>{ res.send({status : true, message : "sample JSON"})})
If you are using router you coudn't use get method.
Here is the docs.
Only the handler has access to get method. app.use will add path to api route which point to get,post and etc.
You could only explicitly define a get as a standalone get route.
app.get('/route1', (req, res) => {
res.send("You have hit route1 - get");
});
When using router you could only include the router object as a parameter in app.use(path, routerObj) method.
app.get('/route1', routes);
woulde be app.use('/route1', routes);

Expressjs - TypeError: Cannot read property 'apply' of undefined

I know there are other questions about this error, but none of them helped me. Everything was working fine untill I decided to add consign and change my directories structure.
I tried changing the orders my route is being loaded, but did not work
This is server.js:
'use strict';
const express = require('express');
const consign = require('consign');
const path = require('path');
const cookieParser = require('cookie-parser');
const porta = 3000;
const app = express();
const pathFront = '../app/front/';
//app.use(require('../app/routes/'));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, pathFront + 'public')));
app.set('views', path.join(__dirname, pathFront + 'views'));
app.set('view engine', 'pug');
app.use(require('../app/routes/')); // still not working
// Tried to change the include order, did not work
consign()
.include('./app/routes')
.then('./config/db.js')
.then('./app/back/api/models')
.then('./app/back/api/controllers')
.into(app);
module.exports = app;
This is route index:
'use strict';
var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
res.render('index', { title: 'API' });
});
/* ENDPOINTS*/
/*
/languages -- all
/language?idLanguage
/language?name=
/languages?idCategory
/language?name=
/categories
//
*/
module.exports = router;
This is folder structure:
And running npm start:
Going by your sample code, you don't seem to be using consign correctly. The included files (using .include or .then there after) should export one function which takes the express app as parameter. Check this example in consign repo. Functions from each of the included file is called with the object which you provide to .into(). You can very well let go of consign, and manually require and use each fo the files, which seems to be working as per your comments.
Otherwise you can change your routes files to something like this:
server.js doesn't change.
app/routes/index.js changes to following:
'use strict';
var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
res.render('index', { title: 'API' });
});
/* ENDPOINTS*/
/*
/languages -- all
/language?idLanguage
/language?name=
/languages?idCategory
/language?name=
/categories
//
*/
module.exports = function (app) {
app.use('/', router);
}
Followed by similar changes in all other files that you'd use with consign.

NodeJS parse middleware to Controller/Route

I'm starting now with NodeJS and I'm having a problem accessing some functions in controllers with express.
Example:
My server.js:
var express = require('express');
var consign = require('consign');
var bodyParser = require('body-parser');
var expressValidator = require('express-validator');
var Recaptcha = require('express-recaptcha');
var recaptcha = new Recaptcha('blablabla', 'blablabla');
var app = express();
app.set('view engine', 'ejs');
app.set('views', 'app/views');
app.use(express.static('./app/public'));
consign()
.include('./app/routes')
.then('./app/models')
.then('./app/controllers')
.into(app);
module.exports = app;
app.listen(3000, function () {
console.log('Server ON');
});
My app/routes/home.js route:
module.exports = function (myapp) {
myapp.get('/site', recaptcha.middleware.render, function (req, res) {
myapp.app.controllers.home.pagina(myapp, req, res, {title: 'Cadastre-se', url: req.originalUrl, captcha: res.recaptcha});
});
};
My app/controllers/home.js controller:
module.exports.pagina = function (myapp, req, res, page) {
res.render("index", page);
};
You are returning the error:
ReferenceError: recaptcha is not defined at Function.module.exports (/Users/User/NodeJS_projects/myapp/app/routes/home.js:2)
If I call the middleware in the server.js file as follows:
...ss.static('./app/public'));
app.use(recaptcha());
consign()...
Returns the following error:
TypeError: recaptcha is not a function
How to solve this problem? Or, what would be the correct way to pass a middleware to controllers or routes?
There are a couple of issues. One, if you look at the documentation for the express-recaptcha module here, you need to parse the request body for this module to work. To do this you need the body-parser module, which you correctly have, but you also need to add the middleware:
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
You can add this right after defining app in your server.js file. Then, you do not have recaptcha defined in your home.js file. You can move the following definition from server.js to home.js:
var Recaptcha = require('express-recaptcha');
var recaptcha = new Recaptcha('blablabla', 'blablabla');
Also, you added app.use(recaptcha()); to your server.js file. recaptcha is not a function itself. It contains two middleware functions, one for rendering the widget (recaptcha.middleware.render) and the other for verifying the response from the widget (recaptcha.middleware.verify). These should be added to specific routes that are in charge of rendering and verification. I think if you look at the link I provided, it will be helpful.

NodeJs routes not working from inner page

I am trying to develop an application in NodeJs using express framework. My routing is working when I navigating from home to inner pages. But If I want to navigate from some inner page to homepage then it is not working.
Below is my app.js code.
const express = require('express');
const path = require('path');
const engines = require('consolidate');
const bodyParser = require('body-parser');
//declare all routers
var home = require(path.join(__dirname, "/routes/index"));
var myaccount = require(path.join(__dirname, "/routes/myaccount"));
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.engine('html', engines.handlebars);
var defaultViewPath = path.join(__dirname, "/views");
app.set('views', defaultViewPath);
app.set('view engine', 'html');
app.use('/', home);
app.use('/myaccount', myaccount);
Here if I have navigated from home to myaccount - Its working
But if I am navigating from myaacount to home - It reloads the same page.
Can anyone help me to resolve this issue.
To define routing using methods of the Express app object, use app.get() to handle GET requests
var express = require('express')
var app = express()
// When GET request is made to the homepage
app.get('/', function (req, res) {
res.render('home');
});
// When GET request is made to the myaccount
app.get('/myaccount', function (req, res) {
res.render('myaccount');
});
app.get('/myaccount/innerpage', function (req, res) {
res.send('Hello Inner Page');
});
//Page Not Found
app.use(function(req, res){
//render the html page
//res.render('404');
res.sendStatus(404);
});
Hope this could help you
use app.get and app.post Route Methods
app.get('/',function(req,res){
res.render('home');
});
app.get('/myaccount',function(req,res){
res.render('myaccount');
});
Or Create Router File For Home & myAccount
var express = require('express')
var router = express.Router()
router.get('/', function (req, res) {
res.send('Home Page')
})
module.exports = router
in Your app.js or index.js file , require route.js
var home = require('./route');
app.use('/', home)

ERROR app.use() requires middleware functions: (so how to set router for app.use in express node.js)?

basically im just trying to seprate routes, models, and controller in node.js application.
i have following files to setup very very basic node.js application.
controller/cv.js
module.exports = {
get: function(req, res, next){
console.log("GET REQUESTS")
next();
}
}
routes/cv.js
var express = require('express');
var CvRouter = express.Router();
var CvController = require('../controller/cv')
CvRouter.get('/', function(req, res, next){
console.log("GET REQUESTS")
next();
})
module.export = CvRouter
app.js
const express = require('express');
const bodyParser= require('body-parser')
var path = require('path')
const app = express();
app.use(bodyParser.urlencoded({extended: true}))
app.use(bodyParser.json())
var router = express.Router();
require('./router')(app)
app.listen(3000, function() {
console.log('listening on 3000')
})
router.js
var CvRouter = require('./routes/cv')
module.exports = function(app) {
app.use([CvRouter]);
};
Basicaly this last file router.js is generting error when i use app.use([CvRouter])
ERROR is: throw new TypeError('app.use() requires middleware functions');
how i can resolve it? i also know its returning object of router. and app.use expecting function in parameter. but how i can achieve my desired MVC pattern of node.js?
as said in comment - you have a typo.
The file routes/cv.js contains module.export instead of module.exports, that makes CvRouter undefined.
Kill the array literal
var CvRouter = require('./routes/cv')
module.exports = function(app) {
app.use(CvRouter);
};

Resources