Route.get() requires callback functions but got a "object Undefined"

node.jsExpress

node.js Problem Overview


I am learning making Todo app. On the website, I am studying is https://coderwall.com/p/4gzjqw/build-a-javascript-todo-app-with-express-jade-and-mongodb

I typed as instruction describes,

app.js

var main = require('./routes/main');
var todo = require('./routes/todo');
var todoRouter = express.Router();
app.use('/todos', todoRouter);
app.get('/', main.index);
todoRouter.get('/',todo.all);
todoRouter.post('/create', todo.create);
todoRouter.post('/destroy/:id', todo.destroy);
todoRouter.post('/edit/:id', todo.edit);

/routes/todo.js

module.exports ={
  all: function(req, res){
    res.send('All todos');
  },
  viewOne: function(req, res){
    console.log('Viewing '+req.params.id);
  },
  create: function(req, res){
    console.log('Todo created');
  },
  destroy: function(req, res){
    console.log('Todo deleted');
  },
  edit: function(req, res){
    console.log('Todo '+req.params.id+' updated');
  }
};

and I got this error message

> Error: Route.get() requires callback functions but got a [object > Undefined]

Did I miss something here?

node.js Solutions


Solution 1 - node.js

In the tutorial the todo.all returns a callback object. This is required for the router.get syntax.

From the documentation:

> router.METHOD(path, [callback, ...] callback) > > The router.METHOD() methods provide the routing functionality in > Express, where METHOD is one of the HTTP methods, such as GET, PUT, > POST, and so on, in lowercase. Thus, the actual methods are > router.get(), router.post(), router.put(), and so on.

You still need to define the array of callback objects in your todo files so you can access the proper callback object for your router.

You can see from your tutorial that todo.js contains the array of callback objects (this is what you are accessing when you write todo.all):

module.exports = {
    all: function(req, res){
        res.send('All todos')
    },
    viewOne: function(req, res){
        console.log('Viewing ' + req.params.id);
    },
    create: function(req, res){
        console.log('Todo created')
    },
    destroy: function(req, res){
        console.log('Todo deleted')
    },
    edit: function(req, res){
        console.log('Todo ' + req.params.id + ' updated')
    }
};

Solution 2 - node.js

I got the same error. After debugging, I found that I misspelled the method name that I imported from the controller into the route file. Please check the method name.

Solution 3 - node.js

There are two routes for get:

app.get('/', main.index);
todoRouter.get('/',todo.all);

Error: Route.get() requires callback functions but got a [object Undefined] This exception is thrown when route.getdoes not get a callback function. As you have defined todo.all in todo.js file, but it is unable to find main.index. That's why it works once you define main.index file later on in the tutorial.

Solution 4 - node.js

Make sure that

yourFile.js:

exports.yourFunction = function(a,b){
  //your code
}

matches

app.js

var express = require('express');
var app = express();
var yourModule = require('yourFile');
app.get('/your_path', yourModule.yourFunction);

For me, I ran into this issue when copy pasting a module into another module for testing, needed to change the exports. xxxx at the top of the file

Solution 5 - node.js

Some time you miss below line. add this router will understand this.

module.exports = router;

Solution 6 - node.js

What happened to me is I was exporting a function like this:

module.exports = () => {
    const method = async (req, res) => {
    }
    return {
        method
    }
}

but I was calling it like this:

const main = require('./module');

instead

const main = require('./module')();

Solution 7 - node.js

This thing also happened with my code, but somehow I solved my problem. I checked my routes folder (where my all endpoints are their). I would recommend you check your routes folder file and check whether you forgot to add your particular router link.

Solution 8 - node.js

I had the same error. The problem was in the export and import of the modules.

Example of my solution:

Controller (File: posts.js)

exports.getPosts = (req, res) => {
    res.json({
        posts: [
            { tittle: 'First posts' },
            { tittle: 'Second posts' },
        ]
    });
};

Router (File: posts.js)

const express = require('express');
const { getPosts } = require('../controllers/posts');

const routerPosts = express.Router();
routerPosts.get('/', getPosts);

exports.routerPosts = routerPosts;

Main (File: app.js)

const express = require('express');
const morgan = require('morgan');
const dotenv = require('dotenv');
const { routerPosts } = require('./routes/posts');

const app = express();
const port = process.env.PORT || 3000;

dotenv.config();

// Middleware
app.use(morgan('dev'));

app.use('/', routerPosts);

app.listen(port, () => {
    console.log(`A NodeJS API is listining on port: ${port}`);
});

Running the application (chrome output)

// 20200409002022
// http://localhost:3000/

{
  "posts": [
    {
      "tittle": "First posts"
    },
    {
      "tittle": "Second posts"
    }
  ]
}

Console Log

jmendoza@jmendoza-ThinkPad-T420:~/IdeaProjects/NodeJS-API-Course/Basic-Node-API$ npm run dev

> node-api@1.0.0 dev /home/jmendoza/IdeaProjects/NodeJS-API-Course/Basic-Node-API
> nodemon app.js

[nodemon] 2.0.3
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node app.js`
A NodeJS API is listining on port: 3000
GET / 304 5.093 ms - -
GET / 304 0.714 ms - -
GET / 304 0.653 ms - -
[nodemon] restarting due to changes...
[nodemon] starting `node app.js`
A NodeJS API is listining on port: 3000
GET / 200 4.427 ms - 62
GET / 304 0.783 ms - -
GET / 304 0.642 ms - -

Node Version

jmendoza@jmendoza-ThinkPad-T420:~/IdeaProjects/NodeJS-API-Course/Node-API$ node -v
v13.12.0

NPM Version

jmendoza@jmendoza-ThinkPad-T420:~/IdeaProjects/NodeJS-API-Course/Node-API$ npm -v
6.14.4

Solution 9 - node.js

check your closing tags in your model, it may be that you have defined a callback in another callback

Solution 10 - node.js

My problem was a mistake in importing:

I imported my function into the router/index.js like below:

const { index } = require('../controllers');

and used it like this:

router.get('/', index.index);

This was my mistake. I must have used this:

router.get('/', index);

So I changed it to the line above and my problem got solved.

Solution 11 - node.js

(1) Make sure that you have imported the corresponding controller file in router file

(2) Make sure that the function name written in the any of the router.get() or router.post() in router.js file is exactly same as the function name written in the corresponding controller file

(3) Make sure that you have written module.exports=router; at the bottom of router.js file

Solution 12 - node.js

I ran into this issue too, my issues I did not add {} to my export in the controller file.

something like this,

module.exports = {createVendor};

Solution 13 - node.js

node js and express 4 use this sequences

express = require('express');
var router = express.Router();

module.exports = router;

last line returns this type of error

Solution 14 - node.js

In my case I was trying to 'get' from express app. Instead I had to do SET.

app.set('view engine','pug');

Solution 15 - node.js

Make sure that

When you import some modules from other folders for instance,

 const { test } = require('./ImportedModule/auth')


 app.post("/post/:id", test);

You should double-check that you imported the test from ImportedModule/auth is exist in ImportedModule/auth Module.

Solution 16 - node.js

I solved the problem. I was trying to import the controller file from the controller folder that I created for other normal controller But actually, I was needed to import it from the middleware folder. You might have that issue.

Solution 17 - node.js

My suggestion, if you are still using const XXX = require('library or ./path') when using module.exports to export multiple functions use an ES6 arrow function.

For example:

module.exports = () => { 
    
    const  getPosts = (req, res ) =>{
        res.send('THIS WORKS!');
    }

    const getPost = async (req, res) => { 
        const { id } = req.params;
    
        try {
            const post = await PostMessage.findById(id);
            
            res.status(200).json(post);
        } catch (error) {
            res.status(404).json({ message: error.message });
        }
    }

 }

then Import:

const getPosts = require('../controllers/posts.js');

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionjayko03View Question on Stackoverflow
Solution 1 - node.jsroflmyeggoView Answer on Stackoverflow
Solution 2 - node.jsDiaMaBoView Answer on Stackoverflow
Solution 3 - node.jsNiveshView Answer on Stackoverflow
Solution 4 - node.jsNickView Answer on Stackoverflow
Solution 5 - node.jsYogesh ShettyView Answer on Stackoverflow
Solution 6 - node.jspedrommullerView Answer on Stackoverflow
Solution 7 - node.jsKuldeepView Answer on Stackoverflow
Solution 8 - node.jsJonathan MendozaView Answer on Stackoverflow
Solution 9 - node.jsDanielView Answer on Stackoverflow
Solution 10 - node.jsMahdieh ShavandiView Answer on Stackoverflow
Solution 11 - node.jssoumith tej gajelliView Answer on Stackoverflow
Solution 12 - node.jsGarantorView Answer on Stackoverflow
Solution 13 - node.jsuser5190210View Answer on Stackoverflow
Solution 14 - node.jsRaghavendra MView Answer on Stackoverflow
Solution 15 - node.jsSamim HakimiView Answer on Stackoverflow
Solution 16 - node.jsMizanur RahmanView Answer on Stackoverflow
Solution 17 - node.jsBruno Miyamotto LuqueView Answer on Stackoverflow