user1302430
user1302430

Reputation: 352

Node.JS - fs.exists not working?

I'm a beginner in Node.js, and was having trouble with this piece of code.

var fs = require('fs');

Framework.Router = function() {

    this.run = function(req, res) {
        fs.exists(global.info.controller_file, function(exists) {
            if (exists) {
                            // Here's the problem
                            res.writeHead(200, {'Content-Type':'text/html'});
                var cname = App.ucfirst(global.info.controller)+'Controller';
                var c = require(global.info.controller_file);
                var c = new App[cname]();
                var action = global.info.action;
                c[action].apply(global.info.action, global.info.params);
                            res.end();
            } else {
                App.notFound();
                return false;
            }
        });
    }
};

The problem lies in the part after checking if the 'global.info.controller_file' exists, I can't seem to get the code to work properly inside the: if (exists) { ... NOT WORKING } I tried logging out the values for all the variables in that section, and they have their expected values, however the line: c[action].apply(global.info.action, global.info.params); is not running as expected. It is supposed to call a function in the controller_file and is supposed to do a simple res.write('hello world');. I wasn't having this problem before I started checking for the file using fs.exists. Everything inside the if statement, worked perfectly fine before this check.

Why is the code not running as expected? Why does the request just time out? Does it have something to do with the whole synchronous vs asynchronous thing? (Sorry, I'm a complete beginner)

Thank you

Upvotes: 2

Views: 3855

Answers (1)

Bret Copeland
Bret Copeland

Reputation: 24050

Like others have commented, I would suggest you rewrite your code to bring it more in-line with the Node.js design patterns, then see if your problem still exists. In the meantime, here's something which may help:

The advice about not using require dynamically at "run time" should be heeded, and calling fs.exists() on every request is tremendously wasteful. However, say you want to load all *.js files in a directory (perhaps a "controllers" directory). This is best accomplished using an index.js file.

For example, save the following as app/controllers/index.js

var fs = require('fs');
var files = fs.readdirSync(__dirname);
var dotJs = /\.js$/;
for (var i in files) {
    if (files[i] !== 'index.js' && dotJs.test(files[i]))
        exports[files[i].replace(dotJs, '')] = require('./' + files[i]);
}

Then, at the start of app/router.js, add:

var controllers = require('./controllers');

Now you can access the app/controllers/test.js module by using controllers.test. So, instead of:

fs.exists(controllerFile, function (exists) {
    if (exists) {
        ...
    }
});

simply:

if (controllers[controllerName]) {
    ...
}

This way you can retain the dynamic functionality you desire without unnecessary disk IO.

Upvotes: 4

Related Questions