25

What are the best-practices in order to re-use/share code between an AngularJS client and a Node.js server?

I implemented an AngularJS application. Now I need to implement a RESTful-server providing the client with data. Some client-side angular services could be re-used on server, as for example third-party restful-clients to Facebook/Google/Twitter, which use intensively the angular dependency injection and which are dependent on $http, $q and many other services.

Ideally, as I really like the dependency injection framework included in AngularJS, I would find very nice to have a kind of server-framework based on AngularJS. A server-framework that includes the dependency injection framework and all angular-services that are not related to UI, and adding required server-side functionality like routing and authentication. But unfortunately, I didn't find any solution going that way. (Please tell me if such a framework exists!)

So, what would be an alternative, in order to at least enable code re-use between the client and the server? Particularly enabling code re-use for code depending on $http, $q and other AngularJS services included in the angular framework and angular-third-parties (like angular-cache).

AstroCB
  • 12,337
  • 20
  • 57
  • 73
jeromerg
  • 2,997
  • 2
  • 26
  • 36
  • 3
    Very interesting question. I think sharing models and some business logic is a very interesting idea. For example sharing schema, validation and services could turn into something awesome. Also you should look into node-di. It is a dependancy injection framework heavily inspired by AngularJS. – Kenneth Lynne Mar 31 '14 at 12:30

3 Answers3

6

Using angular in non-browser environment

Ben Clinkinbeard prepared angular distribution as a commonJS module (HERE), that can run in a non-browser environment:

AngularJS compiled with jsdom and provided as a CommonJS module. Intended for testing AngularJS code without depending on a browser.


If you want to be more cherry-picking you probably should wait for angular 2.0

Sharing code between client-side and server-side

And again... Ben Clinkinbeard. In THIS TALK he describes how to make use of browserify in an angular project. One cool feature of this approach is that you can declare your functions/objects as separate entities that are not coupled with angular anyhow; so they can be re-used in different contexts as well.

An example of it:

app.js

var app = angular.module('someModule',[]);
...
app.factory('someService', require('./some/path.js'));
...

./some/path.js

module.exports = function(dep1, dep2){
  ...
  return {
     ...
  }
}
module.exports.$inject['dep1', 'dep2']; // for minification;
artur grzesiak
  • 20,230
  • 5
  • 46
  • 56
  • Hi, a little off topic but I'm doing something similar to what Ben mentioned in that talk. I really like the concept of separating the entity and making them modular. However, I don't know how much you've played with this concept but I'm having the hardest time trying to make my tests run. Everytime I run my mocha test I get `Argument 'SomeController' is not a function, got undefined http://errors.angularjs.org/1.2.21/ng/areq?p0=SomeController&p1=not%20a%20function%2C%20got%20undefined`. I've added the snippet if you want to look around [here](http://jsfiddle.net/rqwgpumy/). – shriek Oct 14 '14 at 05:17
  • It appears as though it's unaware of my controllers. Also, just a side note, `angular` which used to be Ben's package now has been official `angular`'s repo. So, if you do `npm i angular` it will instead give you the browser version of angular :(. But you can always put `"angular": "git://github.com/bclinkinbeard/angular"`in your `package.json` to grab from github. – shriek Oct 14 '14 at 05:24
1

Using RequireJS for this make sense here.

Instead of defining your model/service inside of Angular like this:

(function (angular) {
  "use strict";
  angular.module('myModule').factory('MyModel', function (Deps) {
    var Model = function () {
      // do things here
    };
    return Model;
  });
}(window.angular));

You would do it this way splitting it in 2 files:

model.js:

(function (define) {
  "use strict";
  define([], function () {
    var factoryConstructor = function (deps) {
      var Model = function () {
        // do things here
      };
      return Model;
    };
    return factoryConstructor;
  });
}(window.define));

whatever.js

(function (define, angular) {
  "use strict";
  define(['Model'], function (Model) {
    angular.module("myModule").factory("myModel", Model);
  });
}(window.define, window.angular));

Check this Videos for a good example on how to implement this, there is also the repository from that video.

Dave Newton
  • 158,873
  • 26
  • 254
  • 302
Yahya KACEM
  • 2,481
  • 7
  • 34
  • 61
1

Angular 1.x is pretty self contained framework. There is a plan to break functionalities apart, but that will come in version 2. So this would be simple as just provide different implementation of $httpBackend for browser and node.js.

I have created a simple demo how to share code between node.js and browser with CommonJS. This can be used for sharing validation, models etc.

Matjaz Lipus
  • 702
  • 1
  • 5
  • 10