23
votes

This is my server.js file and api.js file. I am getting an error in the sort function in which I intend to search the js objects according to their attributes.The event Schema has the attributes as name, location, price, rating. I tried to sort it according to their prices.

server.js

var express= require('express');
var bodyParser= require('body-parser');
var morgan = require('morgan');
var config=require('./config');
var app= express();
var mongoose=require('mongoose');
//var User=require('./database/user')
mongoose.connect('mongodb://localhost:27017/db',function(err){
    if(err){
        console.log(err);
    }
    else{
        console.log("connected!");
    }
});

app.use(bodyParser.urlencoded({extended: true })); //if false then parse only strings
app.use(bodyParser.json());
app.use(morgan('dev'));//log all the requests to the console
var api=require('./app/routes/api')(app,express);
app.use('/api',api);
app.get('*',function(req,res){
    res.sendFile(__dirname + '/public/views/index.html');
});   // * means any route

app.listen(config.port,function(err){
    if(err){enter code here
        console.log(err);
    }
    else{
        console.log("The server is running");
    }
});
module.exports = router;

api.js

var User = require('../models/user');
var Event = require('../models/event');
var config = require('../../config');
var secret = config.secretKey;

module.exports = function (app, express) {
    var api = express.Router();
    app.use()

    api.post('/signup', function (req, res) {
        var user = new User({
            name: req.body.name,
            username: req.body.username,
            password: req.body.password
        });
        user.save(function (err) {
            if (err) {
                res.send(err);
                return;
            }
            res.json({
                message: 'User created!'
            });
        });

    });

    api.get('/users', function (req, res) {
        User.find({}, function (err, users) {
            if (err) {
                res.send(err);
                return;
            }
            res.json(users);
        });
    });

    api.post('/eventfeed', function (req, res) {
        var event = new Event({
            name: req.body.name,
            location: req.body.location,
            description: req.body.description,
            price: req.body.price,
            rating: req.body.rating
        });

        event.save(function (err) {
            if (err) {
                res.send(err);
                return;
            }
            res.json({
                message: 'Event created!'
            });
        });
    });

    // utility function for sorting an array by a key in alpha order
    api.get('/sortby_price', function (err) {
        if (err) return err;
            // utility function for sorting an array by a key in parsed numeric order
        else {
            function sortArrayNum(arr, key) {
                arr.sort(function (a, b) {
                    return parseInt(a[key], 10) - parseInt(b[key], 10);
                });
            }

            var dicts = EventSchema.saved;
            for (var i = 0; i < dicts.length; i++) {
                var terms = dicts[i].terms;
                sortArrayNum(terms, "price");
            }
        }
        return api;
    });
}

This is my error. I am making a webpage for the first time using this. Kindly help me what does this error tells.

TypeError: app.use() requires middleware functions
at EventEmitter.use (c:\Users\MY APY\WebstormProjects\Main\node_modules\express\lib\application.js:209:11)
at module.exports (c:\Users\MY LAPY\WebstormProjects\Main\app\routes\api.js:10:9)
at Object. (c:\Users\MY LAPY\WebstormProjects\Main\server.js:20:36)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:501:10)
at startup (node.js:129:16)
at node.js:814:3

4

4 Answers

60
votes

I had this problem when I left out

module.exports = router;

in my Routes.js.We need to export all the routes.

In my server.js, I had

var mainRoutes = require('./Routes.js')
app.use(mainRoutes)

So check your 'app/routes/api' file to see if it has proper export.

11
votes

Middleware is a function with access to the request object (req), the response object (res), and the next middleware in the application’s request-response cycle, commonly denoted by a variable named next.

Middleware can:

  • Execute any code.
  • Make changes to the request and the response objects.
  • End the request-response cycle.
  • Call the next middleware in the stack.

If the current middleware does not end the request-response cycle, it must call next() to pass control to the next middleware, otherwise the request will be left hanging.

In api.js line number 10 is invalid

app.use()

app.use must have a function with 3 params

// a middleware with no mount path; gets executed for every request to the app
app.use(function (req, res, next) {
   console.log('Time:', Date.now());
   next();
});

if you want only few selected paths to use this middleware you can do something like this

// a middleware mounted on /user/:id; will be executed for any type of HTTP request to /user/:id
app.use('/user/:id', function (req, res, next) {
   console.log('Request Type:', req.method);
   next();
});

// a route and its handler function (middleware system) which handles GET requests to /user/:id
app.get('/user/:id', function (req, res, next) {
   res.send('USER');
});

Take a look at the expressjs documents it is pretty good. http://expressjs.com/guide/using-middleware.html

5
votes

You need to export your router in bottom of route file

like this module.exports = router;

and use in app.js file

const mainRoutes = require('./Routes.js')
app.use(mainRoutes)

Enjoy!

3
votes

app.use requires that you pass it a function which is then used as middleware. You have two instances where you do not do this which will cause this error; both of which are in api.js.

api.js:10 app.use()

You do not pass a function to .use(), and so this will cause an error. This is the error you're seeing in your post.

However, you will get another error:

var api=require('./app/routes/api')(app,express);
app.use('/api',api);

This section attempts to mount the return value of your ./app/routes/api module function as a middleware. However, we can see inside your code that you do not actually return a value from the function in api.js; you instead return the router from inside a route handler..

// utility function for sorting an array by a key in alpha order
api.get('/sortby_price', function (err) {
    if (err) return err;
        // utility function for sorting an array by a key in parsed numeric order
    else {
        function sortArrayNum(arr, key) {
            arr.sort(function (a, b) {
                return parseInt(a[key], 10) - parseInt(b[key], 10);
            });
        }

        var dicts = EventSchema.saved;
        for (var i = 0; i < dicts.length; i++) {
            var terms = dicts[i].terms;
            sortArrayNum(terms, "price");
        }
    }
    return api; // <- this will be returned inside the app.get call
});

You should instead move this out of the handler and to the end of your function.

The total amended code will look like this:

module.exports = function (app, express) {
    var api = express.Router();
    ..omitted for brevity..

    // utility function for sorting an array by a key in alpha order
    api.get('/sortby_price', function (err) {
        if (err) return err;
            // utility function for sorting an array by a key in parsed numeric order
        else {
            function sortArrayNum(arr, key) {
                arr.sort(function (a, b) {
                    return parseInt(a[key], 10) - parseInt(b[key], 10);
                });
            }

            var dicts = EventSchema.saved;
            for (var i = 0; i < dicts.length; i++) {
                var terms = dicts[i].terms;
                sortArrayNum(terms, "price");
            }
        }
    });
    return api;
}