How to break this Node code into different files - javascript

I want to put code such as
app.use("/localAssets", express.static(__dirname + '/localAssets'));
app.use("/scripts", express.static(__dirname + '/scripts'));
in a different file, right now it is in the main server file but I do not like that. I also don't like that all the scoket event handling is also in the main server file.
ie
function onSocketConnection(client) {
//player connected
// Listen for client disconnected
client.on("disconnect", onClientDisconnect);
client.on('sendMessage', function (data) {
this.broadcast.emit('message', data);
this.emit('message', { text: data.text});
});
// Listen for new player message
client.on("new player", onNewPlayer);
// Listen for move player message
client.on("move player", onMovePlayer);
client.on("update health", onUpdateHealth);
client.on("attack hits", onHitByAttack);
client.on("meteor cast", onMeteorCast)
};
function onClientDisconnect() {
...
}
Please advise!
Here is the full file I want to sort out:
https://gist.github.com/hassanshaikley/337e5b7b7a8206a54418

Just put anything you want into different files inside of a function like this:
module.exports = function() {
// your code here
};
Then require and call that function, passing in whatever reference it may need, such as app:
// my-file.js
module.exports = function(app) {
// your code here
};
// index.js
require('./path/to/my-file')(app);
Here's a basic example of moving routes into another file:
// index.js
require('./path/to/some-routes')(app);
// some-routes.js
module.exports = function(app) {
app.get('/foo', function(req, res) {
res.send('Hi! This is foo.');
});
app.get('/bar', function(req, res) {
res.send('Hi! This is bar.');
});
app.get('/:me', function(req, res) {
res.send('Hi! This is '+req.params.me);
});
};

Related

Cannot GET /the route Error

I'm following this tutorial (source code) and added the highlighted code.
// app.js
app.get("/notebooks", function(req, res) {
var client = new Evernote.Client({ token: req.session.oauthAccessToken }),
noteStore = client.getNoteStore();
noteStore.listNotebooks(function(err, noteBooks) {
res.send(err || noteBooks);
});
});
app.get('/importNotes', function (req, res) {
res.send('importNotes');
});
app.get("/notes/:guid", function(req, res) {
var client = new Evernote.Client({ token: req.session.oauthAccessToken }),
noteStore = client.getNoteStore();
noteStore.getNote(req.params.guid, true, true, true, true, function(err, note) {
if (!err) {
note.content = ENML.HTMLOfENML(note.content, note.resources);
}
res.send(err || note);
});
});
another attempt:
app.get('/importNotes', function (req, res) {
res.render('importNotes', {});
});
I created importNotes.html near to index.html.
After starting the server with node app.js
I'm getting an error stating Cannot GET /importNotes
when I access localhost:3000/importNotes
I plan to use this page to add additional features after I deal with this issue (import the notes from the special txt file).
What I'm doing wrong and how I can correct it?
How to define correctly the needed routes ?
This is Steve - thanks for trying out the code !
If you use this code :
app.get('/importNotes', function (req, res) {
res.send('importNotes');
});
Then I would expect the server will send back to the browser the string "importNotes". Perhaps if you have a file called "importNotes" there is some confusion.
If you want to create a file called importNotes.html - then just put it into the "public" folder. It will then be accessible via localhost:3000/importNotes.html
The line :
app.use(express.static(__dirname + "/public"));
Tells Express to serve the contents of the "public" folder at the root level of your application, so any files you put in that folder should be GETable. e.g.
/public
index.html
steve.html
localhost:3000/steve.html

SailsJs controller context

Does anybody know proper way to pass context to sails controllers action?
Here is my case why I want to do it:
--- AbstractPageController.js ---
module.exports = {
_getPageData: function(req, res) {
return {
data: {
title: this._getTitle(req, res), // if do nothing "this" is global object
menu: this._getMenu(req, res)
}
};
},
_getTitle: function(req, res) { return 'Cool Page'; },
_getMenu: function(req, res) { return [{ href: '/logout' }]; }
};
--- ConcretePageController.js ---
var _ = require('lodash');
_super = require('./AbstractPageController.js');
module.exports = _.merge({}, _super, {
'main': function(req, res) {
res.view('pageTemplate', this._getPageData(req, res));
},
_getTitle: function(req, res) {
return 'Absolutely - ' + _super._getTitle(req, res);
},
_getMenu: function(req, res) {
return [{ href: '/main/'}].concat(_super._getMenu(req, res));
}
});
That's why I need context.
For this particular case I found this solution:
--- routes.js ---
var concreteController = require('../api/controllers/ConcretePageController.js');
module.exports.routes = {
'/concrete_page': function(req, res) { concreteController.main(req, res); }
}
But it seems a little bit ugly and sails hooks (for example policies) stop works.
I was thinking about the other way. The main point of this, is to move all logic to services and to use a simple inheritance. But this seems strange for me too
Any ideas about a better way to reach the cases I have wrote?
P.S. All code I have wrote above is just an example.
I think you whant to pre-set some data to send to view template, right?
is yes you can use one Before hook ( like midleware ) or sails police
I use the sails hook for preload sails features from npm modules in we-plugin https://github.com/wejs/we-plugin
Check this hook for how load user locale in all requests after controllers :
Link: https://github.com/wejs/we-example/blob/master/api/hooks/we-locale/index.js#L15
You should just reference the controller directly
sails.controllers.yourControllerName.getTitle()
https://stackoverflow.com/a/20994036/1821723

node.js and express file uploader

So I am following this tutorial: http://thejackalofjavascript.com/uploading-files-made-fun/
I have followed the steps all the way up to where they create the routes and haven't actually created any views. It says
Thats it we are all done with our server. Restart your server and
navigate to http://localhost:3000/upload. You should see a JSON
response with the empty array of files.
However when I try to run app.js it sits for a few seconds and then just goes back to the command prompt. No errors are given and I am clueless as to how to fix this.
Here is my code in routes/uploadManager.js
var options = {
tmpDir: __dirname + '/../public/uploaded/tmp',
uploadDir: __dirname + '/../public/uploaded/files',
uploadUrl: '/uploaded/files/',
maxPostSize: 11000000000, // 11 GB
minFileSize: 1,
maxFileSize: 10000000000, // 10 GB
acceptFileTypes: /.+/i,
// Files not matched by this regular expression force a download dialog,
// to prevent executing any scripts in the context of the service domain:
inlineFileTypes: /\.(gif|jpe?g|png)/i,
imageTypes: /\.(gif|jpe?g|png)/i,
imageVersions: {
width: 80,
height: 80
},
accessControl: {
allowOrigin: '*',
allowMethods: 'OPTIONS, HEAD, GET, POST, PUT, DELETE',
allowHeaders: 'Content-Type, Content-Range, Content-Disposition'
},
storage : {
type : 'local'
}
};
var uploader = require('blueimp-file-upload-expressjs')(options);
module.exports = function (router) {
router.get('/upload', function (req, res) {
uploader.get(req, res, function (obj) {
res.send(JSON.stringify(obj));
});
});
router.post('/upload', function (req, res) {
uploader.post(req, res, function (obj) {
res.send(JSON.stringify(obj));
});
});
router.delete('/uploaded/files/:name', function (req, res) {
uploader.delete(req, res, function (obj) {
res.send(JSON.stringify(obj));
});
});
return router;
}
I apologize. I was trying to run node app.js when I was supposed to be running node bin/www since this is an express.js app.

Embed a property or method on the app object inside of controller

I´m trying associate a method or a property on a app object in kraken.js application, like follows:
controllers/index.js
'use strict';
var IndexModel = require('../models/index');
module.exports = function (app) {
var model = new IndexModel();
app.get('/', function (req, res) {
console.log(app.adventurer);
/* Console should be showing "Bilbo Bagins", but I'm getting 'undefined'.
* See the next source file. */
res.render('index', model);
});
};
/index.js
var kraken = require('kraken-js'),
app = {
adventurer: 'Bilbo Bagins'
};
app.configure = function configure(nconf, next) {
// Async method run on startup.
next(null);
};
app.requestStart = function requestStart(server) {
// Run before most express middleware has been registered.
};
app.requestBeforeRoute = function requestBeforeRoute(server) {
// Run before any routes have been added.
};
app.requestAfterRoute = function requestAfterRoute(server) {
// Run after all routes have been added.
};
if (require.main === module) {
kraken.create(app).listen(function (err) {
if (err) {
console.error(err.stack);
}
});
}
module.exports = app;
Also, i´ve tried publish the property on /config/app.json
Any Thoughts?
Simply add the following key to .config/app.json or make a new .config/app-development.json:
"adventurer": "bilbo"
app.json will look like this:
{
//blah
//blah
"adventurer": "bilbo"
}
and then in ./index.js do this in configure:
app.configure = function configure(nconf, next) {
// Async method run on startup.
next(null);
console.log('my traveler is: ', nconf.get('adventurer'));
};
In response to your comment, if you want to get an app config from the ./controllers/index.js then require the nconf lib and use nconf.get like so:
'use strict';
var nconf = require('nconf');
var IndexModel = require('../models/index');
module.exports = function (app) {
var model = new IndexModel();
//or attach it directly to the app object like so
app.set('adventurer', nconf.get('adventurer'));
console.log('adventurer directly set on app object', app.get('adventurer'));
console.log('controller with app adventurer:', nconf.get('adventurer'));
app.get('/', function (req, res) {
res.render('index', model);
});
};
Fire it up with npm start and watch the console. Peace!

flatiron.js routing and templating with union, director and plates?

Coming from express.js, I want to give flatiron a try for a small project. However, there are some small problems which keep me from actually getting somewhere.
var flatiron = require('flatiron')
, session = require('connect').session
, ecstatic = require('ecstatic')
, path = require('path')
, fs = require('fs')
, plates = require('plates')
, director = require('director')
, winston = require('winston')
, union = require('union');
var router = new director.http.Router();
var server = union.createServer({
before: [
ecstatic(__dirname + '/public')
]
});
router.get('/', function () {
var self = this;
fs.readFile('public/layout.html', 'utf-8', function(err, html) {
[...]
})
});
server.listen(3000, function () {
console.log('Application is now started on port 3000');
});
How does routing with director work? When I leave ecstatic out, I can define routes like '/' and it works, but then I don't get static CSS and JS content. With ecstatic / is replaced with 'index.html' and ecstatic has priority over all defined routes.
- It's the same behavior with connect-static. Route (/) is replaced by index.html.
I also tried a different approach using the connect middleware, which doesn't work:
var flatiron = require('flatiron')
, connect = require('connect')
, path = require('path')
, fs = require('fs')
, plates = require('plates')
, app = flatiron.app;
app.use(flatiron.plugins.http);
app.use(connect.favicon());
app.use(connect.static(__dirname + '/public'));
app.use(connect.directory(__dirname + '/public'));
app.use(connect.cookieParser('my secret here'));
app.use(connect.session({'secret': 'keyboard cat'}));
app.router.get('/', function () {
console.log("GET /");
var self = this;
fs.readFile('public/layout.html', 'utf-8', function(err, html) {
[...]
})
});
app.listen(3000, function () {
console.log('Application is now started on port 3000');
});
I think the best answer for your question about routing in flatiron is, as always, inside the source code:
app.server = union.createServer({
after: app.http.after,
before: app.http.before.concat(function (req, res) {
if (!app.router.dispatch(req, res, app.http.onError || union.errorHandler)) {
if (!app.http.onError) res.emit('next');
}
}),
headers: app.http.headers,
limit: app.http.limit
});
As you can see here flatiron binds router as the last request handler, that is called after all middleware. If you place 'ecstatic' in app.http.before and it will be dispatched during workflow, no other middleware would be called.
Your second block of code demonstrates that you don't undestand difference between Flatiron's .use() method from Express/Connect's. I'll try to make it clear on this example:
flatironApp.use({
// plugin object
name : "pluginName"
, attach : function(options) {
/*code*/
}
, init : function(done) {
/*code*/
done();
}
})
connectApp.use(function(req, res, next) {
/* code */
next();
})
If you want to use Connect's middleware in Flatiron you should place it respectively in app.http.before array like this:
// Initiating application
app.use(flatiron.plugins.http);
// Adding request handlers
app.http.before.push( connect.favicon() );
app.http.before.push( ecstatic(__dirname + '/public') );
var connect = require('connect');
var server = union.createServer({
before: [
function (req, res) {
var found = router.dispatch(req, res);
if (!found) {
res.emit('next');
}
},
connect.static('public')
]
});
I forgot to insert the dispatch-function. This works.

Categories