Since a few weeks, I’m testing MeteorJS and I really like it !
The 0.6 version has been released with NPM Integration. Which means that you can use any Node package without the need to tweak your Meteor Application.
At the time of writing, there is no official documentation about this point, only a github demo with xml2js.
This article is a short how-to about :
- NPM Integration
- Invoke functions from client to server
- Use asynchronous methods on server with Fibers & Future
Let’s try to use freebox-sdk with a newly created Meteor Application.
1 2 3 4 5 | $ meteor update #update meteor $ meteor create freebox #create a new project $ cd freebox $ meteor #run your application => Meteor server running on: http://localhost:3000/ |
Meteor should run your newly created Application. Check that you get the Running message without any error. If you got some, just try to fix them 😉
Create the packages directory structure.
1 2 3 | $ mkdir packages && cd packages $ mkdir freebox-sdk && cd freebox-sdk $ touch package.js freebox-sdk.js |
1 2 3 4 5 6 7 8 | // file: package.js Npm.depends({ 'freebox-sdk': '0.3.0' }); Package.on_use(function(api) { api.add_files('freebox-sdk.js', 'server'); }); |
The package.js contains the dependency definition.
When the package will be available, the freebox-sdk.js file will be added to the server scope.
1 2 3 4 5 6 7 | // file: freebox-sdk.js Freebox = Npm.require("freebox-sdk"); freeboxFacade = { get: function(options) { return new Freebox(options); } }; |
Freebox & freeboxFacade are new global variables and are available on your Meteor Application.
For this use case, I have defined a useless Facade for the freebox-sdk package.
Use the var keyword to define variable only attached to this file.
At this point, freebox-sdk is automatically downloaded & attached to Meteor through Freebox & freeboxFacade variables.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | // file: freebox.js if (Meteor.isClient) { Template.hello.events({ 'click input[name="status"]' : function () { Meteor.call('getStatus', jQuery('input[name="password"]').val(), function(error, result) { if(_.isString(result)) { console.log('message: ' + result); } else { console.log('wifi active: ' + result.active); } }); } }); } if (Meteor.isServer) { Meteor.startup(function () { var Future = Npm.require('fibers/future'); Meteor.methods({ getStatus: function(password) { this.unblock(); var future = new Future(); var freebox = new Freebox({password: password}); freebox.on('connect', function() { freebox.wifiStatus(function (status) { future.ret(status); }); }); freebox.on('error', function(message) { future.ret(message); }); freebox.connect(); // Wait for async to finish before returning // the result return future.wait(); } }); }); } |
The freebox-sdk is composed of asynchronous methods, calls have to be done on server-side. I’m using Fibers to ‘wait’ for async (wifiStatus) to finish before returning the result to the client.
For this example I’m using some Meteor packages : jquery & underscore.
1 2 | $ meteor add jquery $ meteor add underscore |
The HTML part is really simple. Just add a new button
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Now,
Run your meteor application, go to http://localhost:3000/ and open a JS Console. Click on the “Click button” and see if your wifi is enable!
If the NPM module has architecture-specific binary components, bundles built with meteor bundle or meteor deploy will contain the components as built for the developer’s platform and may not run on other platforms.
I think it’s better to use exceptions for error handling, so I’d change line 33 in freebox.js to something like:
`future.throw(new Error(message))`
It’s also worth pointing out that exceptions in server methods get piped down to the client — the client will receive a “500 Internal Server Error” in the error callback. If you want to send down more an error that is visible to the client, throw Meteor.Error (http://docs.meteor.com/#meteor_error)
You just forgot the freebox.html to set the button with name=”status”.
Thx for that article that helped me a lot
Just added ! Thanks for the information.
Armetiz.
Great article!
I’ve been trying to figure out the new NPM dependency system, you filled in the gaps missing from Meteor’s documentation.