Include an object defined outside Angular ecosystem into a factory

profile for Nikola at Stack Overflow, Q&A for professional and enthusiast programmers
I’m a big fan of Stack Overflow and I tend to contribute regularly (am currently in the top 0.X%). In this category (stackoverflow) of posts, I will be posting my top rated questions and answers. This, btw, is allowed as explained in the meta thread here.

I asked this question myself:

We’re having an argument, which I hope you guys will help resolve.

Say I have a simple factory defined like this:

angular.module('myModule', [])

.factory('Fact', function() {
    var Fact = function() {
        var that = {};

        that.var1 = [];
        that.var2 = [];

        return that;
    };

    var fact = {
        get: function() {
            return Fact();
        }
    };

    return fact;
});

I found out that this code will be working if I write it like this:

angular.module('myModule', [])

.factory('Fact', function() {
    var fact = {
        get: function() {
            return Fact();
        }
    };

    return fact;
});


var Fact = function() {
    var that = {};

    that.var1 = [];
    that.var2 = [];

    return that;
};

Namely, I can take this code of the object Fact and put it in some other plain .js file, include it before the Angular one (in index.html file) and this “would work”.

However, I’m trying to resolve an argument that this approach is not good (well, not an Angular approach at that) because then this Fact is “laying around on the global scope”, which is not good.

In which circumstances would you say that this is/isn’t a good solution?

Is there a way to include a “nonAngular” code (simple JavaScript code written in some .js file) into the Angular factory?

I accepted the answer from user Dan Prince:

Between factories, services, providers, constants and values, there’s not really a good reason to have any code outside of Angular’s constructs unless it’s third party code.

If it is, you won’t have control over the way that the library, framework, etc registers itself. It might use the global scope, alternatively, it might provide a module export.

Where possible, the cleanest and safest way to include third party code inside Angular is with a build-step using a module bundler.

For instance, I want to use the hypothetical package foojs from inside Angular using browserify:

Install the package with npm

npm install --save foojs

Then use it like this.

var foojs = require('foojs');

var app = angular.app('myapp')

app.service('myservice', function() {
  // here we can use foojs safely
});

You can also achieve similar things with WebPack.

The reason this is safer is because after the build step, all the modules will be wrapped inside a function that protects the global scope.

If you aren’t able to use a module bundler, then the only option is to use the global scope and allow the third party code to bind onto the window object.

https://twitter.com/HitmanHR/status/676654486115454976

Written by Nikola Brežnjak