AngularJS + RequireJS

While delivering software projects for startups, we’ve come to love AngularJS. We’ve also come to struggle with clean modularity, both the parts that Angular does really well, and the parts that are somewhat missing. RequireJS does a great job where Angular leaves some things to be desired, but using them together is not entirely trivial. What follows is our take at the problem.

Why?

Working with Angular you could worry about a good way to organize code. There are already great how-tos on that, check out this mainly theoretical post by Brian Ford and this practical guide by Cliff Meyers if you haven’t already. I’ll share the way I’m managing code in Angular applications with RequireJS.

Continue reading if you want to:

  • stop worrying about including script tags in the right order when building Angular apps;
  • to load your javascript asynchronously;
  • to compile code into single minified js file;

Who?

I assume that you already know what AngularJS is and that you’ve at least heard of AMD and RequireJS. To illustrate the approach I’ll first enable RequireJS for Angular Seed and explain process. Angular Seed structures code by splitting files by type and so will I. It’s also possible to apply this approach if you write modules by entities (you’ll see it from app.controllers module implementation).

How?

Angular Seed Project

Let’s check how Angular Seed structures code. Check out the example in your browser or on github (copied from Seed):

  • app.js file to bootstrap and set app config;
  • actual implementation files – controllers, services, directives and filters;
  • index.html with all script tags included in right order;
  • or index-async.html that makes use of angular-loader.js and 3-rd party $script loader library to load dependencies asyncronously.

Let’s start the party.

Add RequireJS

Checkout the example in your browser or on github.

Installing dependencies

I used bower to do this for me. See bower.json file:

{
  "name": "AngularJS + RequireJS Example",
  "version": "0.1",
  "main": "index.html",
  "ignore": [
    "**/.*",
    "libs"
  ],
  "dependencies": {
    "angular": "latest",
    "requirejs": "latest",
    "requirejs-domready": "latest"
  }
}

Put the .bowerrc file next to bower.json, run bower install and – poof, we have all we need under libs folder.

index.html

Destruction is a good start. Open Angular Seed’s index.html and remove all the <script> tags. Looks cleaner, doesn’t it? Now switch to creation mode and add single script before closing </body> that will load RequireJS and instruct it to look for config in js/main.js with the data-main attribute:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>My AngularJS AngularJS + RequireJS App</title>
  <link rel="stylesheet" href="css/app.css">
</head>
<body>
  <ul class="menu">
    <li><a href="#/view1">view1</a></li>
    <li><a href="#/view2">view2</a></li>
  </ul>

<div data-ng-view></div>

<div>Angular Require seed app: v<span app-version></span></div>

<script src="lib/requirejs/require.js" data-main="js/main.js"></script>
</body>
</html>

That’s all there’s to it. You can close index.html now, as there is nothing more we need to add to it.

main.js

Time to setup RequireJS config.

require.config({

  // alias libraries paths
    paths: {
        'domReady': '../lib/requirejs-domready/domReady',
        'angular': '../lib/angular/angular'
    },

    // angular does not support AMD out of the box, put it in a shim
    shim: {
        'angular': {
            exports: 'angular'
        }
    },

    // kick start application
    deps: ['./bootstrap']
});

What just happened? In paths we set aliases for the libraries and plugins used, then we defined that angular should be shimmed and that bootstrap.js should be loaded to start the application.

bootstrap.js

We’re bootstrapping angular manually now, that’s what bootstrap.js is for. Note that you don’t need ng-app in your html anymore. Also routes.js, which contains angular routes configuration is included into dependencies list.

Note that in this require module we almost have no use of asynchronous loading and we’ll always have chain of angular -> app -> routes, as they depend on each other: angular needs to be present on a page before setting up application module, which is required to exist when defining routes config.

/**
 * bootstraps angular onto the window.document node
 */
define([
    'require',
    'angular',
    'app',
    'routes'
], function (require, ng) {
    'use strict';

    require(['domReady!'], function (document) {
        ng.bootstrap(document, ['app']);
    });
});

We use domReady RequireJS plugin to make sure that DOM is ready when we start the app. Note that before doing so we’re loading the app.js dependency, in there the main application is defined.

app.js

app.js wraps the definition of the top-level app module and loads the dependencies of its submodules.

define([
    'angular',
    './controllers/index',
    './directives/index',
    './filters/index',
    './services/index'
], function (ng) {
    'use strict';

    return ng.module('app', [
        'app.services',
        'app.controllers',
        'app.filters',
        'app.directives'
    ]);
});

We agreed to have 4 modules by files types: controllers, directives, filters, services – we require these modules to be loaded before defining the main module.

routes.js

Top level routes definition lives here. It is also possible to have modules to set up their own routes (this case is omitted for now in favour of simplicity).

define(['./app'], function (app) {
    'use strict';
    return app.config(['$routeProvider', function ($routeProvider) {
        $routeProvider.when('/view1', {
            templateUrl: 'partials/partial1.html',
            controller: 'MyCtrl1'
        });

        $routeProvider.when('/view2', {
            templateUrl: 'partials/partial2.html',
            controller: 'MyCtrl2'
        });

        $routeProvider.otherwise({
            redirectTo: '/view1'
        });
    }]);
});

Module structure

A module consists of 3 parts:

  • definition;
  • component;
  • loader.

Let’s use the app.controllers module as example.

module definition (controllers/module.js)

It’s just like top level app.js: it defines a module.

define(['angular'], function (ng) {
    'use strict';
    return ng.module('app.controllers', []);
});

This file will be used by the module components to attach themselves to (see next section).

module loader (controllers/index.js)

That’s just an empty define block with all module components included. You don’t need to mention module.js here as it’s already required by components. Loader is included as dependency of top level app module. And that’s actually how RequireJS knows about files to load.

define([
    './my-ctrl-1',
    './my-ctrl-2'
], function () {});

module components (controllers/my-ctrl-1.js)

In the case with the app.controllers module it’ll be controllers. Example of controller wrapped in define is:

define(['./module'], function (controllers) {
    'use strict';
    controllers.controller('MyCtrl1', [function ($scope) {}]);
});

Note that we used reference to ./module.js to attach component to its module.

Conclusion

That’s it. Now you have working Angular application powered by RequireJS. You can enjoy the power of not tracking the order of your scripts anymore and you get some powerful minification tooling to boot.

In next articles I’ll show you how to test this application properly, how to compile it into single file and automate workflows with grunt. All this is already enabled in StarterSquad Angular + Require Seed check it out if you can’t wait (I’m a slow typist).

About StarterSquad

StarterSquad is a community of distributed development teams consisting of freelance developers. We specialize in startups and lean innovation. If you want to know more, read more about how we work and if you need any help with Angular, checkout my team.


Team Spotless, StarterSquad

Do you like the post? Share it with your friends!
  •  
  •  
  •  
  •  

 

Looking for a Lean Startup technical team to build your dream startup? Sign up here. Pay as you go.

  • kuma_d

    but examples/angularjs-requirejs-2 dosen’t work in github.

  • kuma_d

    it seems need to run . but how

  • http://www.startersquad.com/ Dmitry Evseev

    Hi @kuma_d:disqus . Thank you for your catching eye, that somehow slipped my attention. Give me a minute to push a fix. Actually it’s `routes.js` missing as dependency in `app.js`. The app is working now, but without routes

    • http://getkickstrap.com/ ajkochanowicz

      I also cannot get routes working. The example doesn’t use angular-routes.js either. Doesn’t it need that?

  • Jyoti

    Hi,
    I want to use Yo for generating a project structure for angularjs and requirejs. Can you please guide. In fact do you suggest using Yo for it or Angular Seed would be better ?

    • http://www.startersquad.com/ Dmitry Evseev

      Hello @disqus_ZtwR7KWpyr:disqus . Right now there are no angular+require generators available for Yo. Last week I considered to introduce them and enable Yo usage but found no convincing reason to do it (It could be me not getting yo’s idea right). Seed already goes with very basic project structure and all you need to do is to start coding your domain modules.

      Let me know if that does not work and you still have questions.

      • Jyoti

        Thanks Dmitry Evseev…

  • http://getkickstrap.com/ ajkochanowicz

    I get the strange error,

    “Cannot read property ‘ng-1383769929872′ of undefined”

    Looks like ‘ng-‘ appended to a unix date.

    I assume this is coming from this part of angular.js

    var jqCache = JQLite.cache = {},
    jqName = JQLite.expando = ‘ng-‘ + new Date().getTime(),

    And then triggers an error here:

    function JQLiteRemoveData(element, name) {
    var expandoId = element[jqName],
    expandoStore = jqCache[expandoId];

    if (expandoStore) {
    if (name) {
    delete jqCache[expandoId].data[name];
    return;
    }

    if (expandoStore.handle) {
    expandoStore.events.$destroy && expandoStore.handle({}, ‘$destroy’);
    JQLiteOff(element);
    }
    delete jqCache[expandoId];
    element[jqName] = undefined; // ie does not allow deletion of attributes on elements.
    }
    }

    function JQLiteExpandoStore(element, key, value) {
    var expandoId = element[jqName],
    expandoStore = jqCache[expandoId || -1];

    if (isDefined(value)) {
    if (!expandoStore) {
    element[jqName] = expandoId = jqNextId();
    expandoStore = jqCache[expandoId] = {};
    }
    expandoStore[key] = value;
    } else {
    return expandoStore && expandoStore[key];
    }
    }

    Any ideas?

    • http://getkickstrap.com/ ajkochanowicz

      Actually, I think I may have solved this. The domReady code should be different. (http://requirejs.org/docs/api.html#pageload)

      Instead of

      require([‘domReady!’], function (document) {
      ng.bootstrap(document, [‘app’]);
      });

      This should be

      require([‘domReady!’], function (domReady) {
      domReady(function() {
      ng.bootstrap(document, [‘app’]);
      })
      });

      • http://www.startersquad.com/ Dmitry Evseev

        Hi @ajkochanowicz:disqus . It’s either `require([‘domReady!’]` (notice ! in the end) with automatic execution of define callback or `require([‘domReady’]` and manual triggering as you described.

        • http://getkickstrap.com/ ajkochanowicz

          I have the ! in both. The difference is the function calling back “document” instead of domReady

  • Kevin Eduardo

    I test this repo with Angular 1.2.2 and it doesn’t work, only with 1.0.8.

    • http://www.startersquad.com/ Dmitry Evseev

      ngRoute was excluded into its own module. That’s what is needed to take care about. Angular upgrade guide covers these cases. I do successfully use this structure with ng 1.2.3.

    • http://www.startersquad.com/ Dmitry Evseev

      Just released updates to example to show how it works with ng 1.2.3. Give github some time to propagate updates until you can see it in a browser. Meanwhile you can see the code itself: https://github.com/StarterSquad/startersquad.github.com/tree/master/examples/angularjs-requirejs-2

  • Dan Orlando

    Thanks for doing the 1.2.3 update, you may want to update the bower.json to reflect that version of angular.

    • http://www.startersquad.com/ Dmitry Evseev

      Thank you @danorlando:disqus for that hint) Done. I use `latest` as version now. Take care as this is dangerous if you have `bower install/update` as one of your deployment steps. Instead either remove this task and have vendor files checked-in, or use exact versions numbers in bower.json (thanks to @Iwein Fuld for solution).

  • http://goo.gl/pWCewh Max Diachenko

    Nice solution to structure AngularJS application!

    • http://www.startersquad.com/ Dmitry Evseev

      Thanks, Max)

  • Duncan Kimpton

    Thanks for posting this, unfortunately I can’t seem to get it to work.

    Everything appears to go fine until I try and set a property on the scope in my controller.

    define([‘./module’], function(controllers) {
    ‘use strict';
    controllers.controller(‘MyCtrl1′, [function ($scope) {
    $scope.test = “testing…”;
    }]);
    });

    at this point I get an exception in the Chrome console:

    TypeError: Cannot set property ‘test’ of undefined

    This would seem to indicate that the $scope property hasn’t been correctly injected by Angular but I’m struggling to see why.

    I’m linking to angular 1.2.6

    Do you have any idea what could be causing this?
    thanks.

    • Duncan Kimpton

      To answer my own question:

      If I manually request injection of $scope it all seems to work:

      define([‘./module’], function(controllers) {
      ‘use strict';
      controllers.controller(‘MyCtrl1′, [‘$scope’, function ($scope) {
      $scope.test = “testing…”;
      }]);
      });

      Maybe this is something that should be updated in the seed project?

      (or is there another cleaner solution?)

      • http://www.startersquad.com/ Dmitry Evseev

        If you’re wrapping a component function in an array like [function () {}] , then you’re obliged to list dependencies as strings and provide function as a last parameter ( http://docs.angularjs.org/guide/di ). This helps your code to survive minification with mangle enabled ;-)

  • Johnny

    When does the next Article mentioned in the outro come out?
    Cheers

    • http://www.startersquad.com/ Dmitry Evseev

      I already have a draft for it. Going to be there in next next week [or two] ;-)

      • Johnny

        nice

      • Iwein Fuld

        Really? ;p

  • Zachary Lincoln

    Hi Dmitry, this guide has been super helpful – thank you so much! I’m struggling to understand how to load another module into the app though. I’ve got everything set up as you do here, but now i’ve added a thirdparty/ under directives/. In directives/index.js i’ve defined the path to ‘./thirdparty/masonry/masonry’. That masonry.js file defines ‘./module’. ‘/directives/thirdparty/masonry/module.js’ returns “ng.module(‘masonry’, [‘ng’]);”. I’ve added the directives in masonry.js.

    Now I want my app to load the ‘masonry’ module so i’ve added it to the ng.module(‘app’ return in app.js. I get the error: Module ‘masonry’ is not available!

    How do you extend your setup to include more components? Thanks for any advice you can give us!

    • Zachary Lincoln

      I changed ‘/directives/thirdparty/masonry/module.js’ to return “ng.module(‘app.directives’, [‘ng’]);” and now everything works fine. Its going to be a lot of overhead to manipulate all of the directives from the thirdparty bootstrap/angular project though https://github.com/angular-ui/bootstrap/blob/gh-pages/ui-bootstrap-tpls-0.9.0.js. So my question still stands!

    • http://www.startersquad.com/ Dmitry Evseev

      Hi Zachary.

      Thank you for excellent question!
      You’ve done a good job finding a way to add a new module (which means I screwed my job, and described the concept poorly).
      You’re almost there. The setup described in article contains 4 modules with files splitted by their roles: directives, controllers so on.
      You should see each as independent module and you can introduce new components following this sctructure :
      1. Introduce module itself:
      * create dir `modules` under `js`,
      * create dir `masonry` in `modules`,
      * in this folder you should put all the code and have 2 more util files: `index.js` and `module.js`
      * in `module.js` place the definition of masonry module (like `directives/module.js` has)
      * all the components of masonry should be amd modules and should append themselves to `module.js` (following `directives/app-version.js`)
      * `index.js` should list all the pieces of the module excluding `module.js` itself (as it’s alredy required in other files)
      2. Include module into project:
      * in app.js add requirejs dependency `./modules/masonry/index` to define and angularjs ‘masonry’ module as to ‘app’ definition.
      Let me know if you still have questions.

      • Zachary Lincoln

        Thanks for getting back to me, that makes a lot of sense – problem solved!

  • Jeroen Rosenberg

    Thanks a lot for this article. Very clearly written! It still took me a while to get it fully working, because I started of with a generated project using Yeoman (http://yeoman.io). From that setup I liked the ease of running ‘grunt serve’ to popup my app in a browser and automatically applied code changes (without manually refreshing the page). Maybe this is also possible with your setup, but I didn’t quite understand it after reading https://github.com/StarterSquad/angularjs-requirejs-seed/

    • http://www.startersquad.com/ Dmitry Evseev

      Hi @jeroenrosenberg:disqus . Yep, it’s possible, livereload script is responsible to do it. It’s a part of grunt watch task, also can be run independently via grunt watch:livereload . To use it you’ll need a plugin installed and enabled in a browser.

      • Jeroen Rosenberg

        Cool :) I’ve almost got everything working now (still based on my yeoman generated project). Also the karma unit tests are now nicely working with RequireJS integration.

        I’m still struggling a bit with clashes between bower and requireJS so it seems, because I get a warning/error during the uglifictation process: ‘No “uglify” targets found’. This is probably caused because I removed a few of the bower build instructions which were present in the comments. I thought it wouldn’t be necessary anymore since we only have one script import anyway (main require js entry point). Before requireJS all the ‘vendor’ scripts were wrapped in a block like this:

        When I wrap the line that loads RequireJS, like so:

        it builds successful, but replaces the requireJS line with separate script tags again

        any help is appreciated :)

        • Jeroen Rosenberg

          I ended up removing all the bower instructions from the index.html and manually configuring the uglification in Gruntfile.js. Now it’s all good :)

          • http://www.startersquad.com/ Dmitry Evseev

            Exactly! There is no need in any build scripts against the index.html. It’s ready to be served in the browser with a single require.js script. That’s the cool part – saves a lot of time spent previously on running the builds.

          • Jeroen Rosenberg

            Probably I still need to configure my Gruntfile a bit better regarding uglifying / minification. I tried to mimic the requirejs part of your angular-requirejs-seed project, but I’m still missing something. I’m rather new to grunt.

          • http://josimard.com/ Jo Simard

            Hi Jeroen, I spent quit some time on that lately. There is a lot of catches with AngularJS and minification, especially to avoid breaking dependency injection. I’m now using UglifyJS2 directly instead of a grunt-contrib wrapper. You can check the Gruntfile and build-utils on my similar project: https://github.com/pheno7/angular-requirejs-seed#angularjs-depencency-injection-and-minification

          • Jeroen Rosenberg

            Thanks Jo, I’ll definitely check this out :)

  • Ro

    Hm, I upgraded to 1.2.9 and added the new ngRoute stuff but I’m still and [$injector:modulerr] error.

  • John

    Hi,
    I can’t make the directives work for some reason.
    I try adding to the partials, but to no avail.
    How do you use the directives in this configuration?

    Edited: My bad here. I forgot about the “dashing” style of angular…
    This works:

  • Tobias Mücksch

    Hey Dimitry, thanks for this very helpful article. I have structured my project as suggested in your article and I am really satisfied!

    • http://www.startersquad.com/ Dmitry Evseev

      Nice to hear that :) Thank you for the feedback.

  • yi fu

    I add a test service under services folder, when I try to inject dependency to ‘ngResource’ like this:
    define([‘angular’], function (angular) {
    ‘use strict';
    return angular.module(‘app.services’, [‘ngResource’]);
    });

    angular complain with the following error message:

    Uncaught Error: [$injector:modulerr] Failed to instantiate module app due to:
    Error: [$injector:modulerr] Failed to instantiate module app.services due to:
    Error: [$injector:modulerr] Failed to instantiate module ngResource due to:
    Error: [$injecto……1)

    I am using the latest Angular version 1.2.13

    ——
    I solved this problem by add angular-resource to the project and refer in main.js

  • http://thaiat.github.io Avi Haiat

    Hi, here is the approach I use : http://codrspace.com/thaiat/angularjs-requirejs/
    let me know what u think

  • Ilya

    Thank you for the article.

    > In next articles I’ll show you how to test this application properly, how to compile it into single file and automate workflows with grunt.

    Are you still planning on writing about automation with grunt?

    • http://www.startersquad.com/ Dmitry Evseev

      Yep, I’m already using all this staff in a seed project (there is a link in the end of an article) – you can go there and pick up all the sweet from it. That’s the main reason I’ve still not introduced an article itself.

      And btw if you need grunt workflow look in repo history, not so long ago we’ve switched to gulp.

  • Mike

    How exactly would you include/create a directive using this? Sorry I am pretty new to angular directives, and have never used requirejs until now

  • seba

    How should I integrate restangular into the party? Can’t seem to get it working ( lodash is present, but [$injector:modulerr] errors)

  • Maxim Milovanov
  • András Tóth

    Can someone show me a scenario where simply loading components in this order won’t work? (using a generator to create a requirejs shim config) What are the advantages of defining dependencies manually?

    (0. libraries)
    1. app definition
    2. other module definitions
    3. controllers, directives, etc.
    4. bootstrap the application

  • Pavel Pavlov

    Hi, and how it works with r.js optimization?

  • Cyruxx

    Hey there. Thank you for your tutorial.
    I can not get this to work. I wish there was a correct GitHub repository with exact the same steps done. Can you do that? :-)

    • http://startersquad.com/ Dmitry Evseev

      Hi @cyruxx:disqus . Yes, sorry after update of the website links to “view examples in the browser” got broken, but github links are still ok, please check them out. In the meantime I’ll update site to have examples

      • Cyruxx

        Hi @Dimitry Evseev,

        Good!

        For the main.js file I had to add

        deps: [
        ‘./bootstrap’,
        ‘domReady’,
        ‘angular’,
        ‘angular-route’,
        ‘bootstrap’
        ]

        to get angular and the other plugins to work. Did you forget that?
        ‘bootstrap’ is for twitter bootstraps Javascript file.

        After all that I’m still having issues with getting angular to work, even though I have followed your steps.
        It won’t load the controllers.

        • Cyruxx

          The following fixed my problems:
          Add the dependencies to the main.js’s deps array.
          Twitter Bootstrap and the Bootstrap.js file were running into a name conflict. I solved this issue by renaming the ‘bootstrap': ‘../bower_components/bootstrap/dist/js/bootstrap.min’ to ‘tw-bootstrap': ‘../bower_components/bootstrap/dist/js/bootstrap.min’ and renamed all other relations.

  • Pingback: AngularJS + RequireJS not working | Questions and Answers Resource()

  • Madalin

    Hi there. Great tutorial, I’m working on a project and I have started using this, but the project needs the use of maps. I have been looking at getting ui.map to integrate and work with this structure, but I was unsuccessful. I have managed to integrate the ui.utils(http://angular-ui.github.io/ui-utils/) and ui.bootstrap (http://angular-ui.github.io/bootstrap/). Could you check it out and see if it would be possible to integrate it and maybe create a tutorial leading on to that using this tutorial as the starting point? (http://angular-ui.github.io/ui-map/)

    • http://startersquad.com/ Dmitry Evseev

      Hi Madalin , that’s a good question! I can tell for sure that it’s possible to use `ui.map` and anything with this approach.
      To start it’s needed to specify angular and ui.utils as deps of ui.map in the requirejs config:

      “`
      {
      paths: {
      ,
      ‘angular-ui-map': ‘../vendor/angular-ui-map/ui-map’,
      ‘angular-ui-utils': ‘../vendor/angular-ui-utils/ui-utils’
      },

      shim: {
      ‘angular-ui-map': [‘angular’, ‘angular-ui-utils’]
      }

      }
      “`

      After you have this setup you can inject ‘angular-ui-map’ in any module and use it.

      P.S. Thank you for requesting a follow up article about how to use the approach described, I find it motivating to actually do that :)

      • Madalin

        I have done that, but the maps need some initialising to be done before use, and I find that rather tricky. Maybe this gives you a bit more motivation to look into it and see how it would work and maybe post up a tutorial or even hints as comments. Thanks a lot. :)

        • http://startersquad.com/ Dmitry Evseev

          Yes, you are right. It was only the part of solution. I’ve checked one of the recent projects where maps were used and recalled another part. You need to requirejsify google maps, to do that I have file google-maps.js with the content (async is requirejs plugin):

          // convert Google Maps into an AMD module
          define([‘async!//maps.google.com/maps/api/js?v=3&libraries=places&sensor=false&language=nl’],
          function(){
          // return the gmaps namespace for brevity
          return window.google.maps;
          });

          After requiring that module and angular-ui-map from previous message you’re good to go:

          define([
          ‘angular’,
          ‘./google-maps’,
          ‘angular-ui-map’,
          ], function (angular, Maps) {
          // in Maps is google map object
          });

          By the way you can see this method at https://vandebron.nl/#!/s/?houseTypeIdx=1&residentTypeIdx=2&meterTypeIdx=1&propositionTypeIdx=FE3-1410

          It’s built with ngSeed

  • http://aacanakin.com/ Aras Can Akin

    Hi. I’ve made the same file structure here. However, after a bunch of page refreshes, the app sometimes crashes. I think there is a race condition here. Is there any solution to that ?

    • http://startersquad.com/ Dmitry Evseev

      Yes, usually race conditions are hard to catch but not to fix. Define which library throws an error and which error. E.g. “ui.bootstrap: angular is not defined” – then add dependency into a shim.

      • http://aacanakin.com/ Aras Can Akin

        Yes it worked. for each shim like ngRoute, it is needed here to add angular dependency. Thanks for the reply!

  • Shawn Rebelo

    I think I will wait for something that makes more sense, not overboard in learning and all around ‘simpler’ . To me that is just WAY to much to include one single file, or multiple even. Complex is not better. Simpler is better.

    • http://google.com/+Nkansahrexford Nkansah Rexford

      Yeah, I find the above process convoluted.

  • Pingback: One Year and Three Months @ StarterSquad – A Developer’s Journey()

  • Naresh Phuloria

    Hello,

    I am looking for lazy loading of controllers and services only when request to specific controller is made. I downloaded you code, and when running the sample solution, all the javascript files within docs, home and ui are loaded with the first request itself.

    I am looking for a solution but so far nothing major is achieved in this part. Can you please share your inputs / insights.

  • johaness vix

    your sample in github is not so simple as you show in tutorial. if I try to download it and run wont works!

  • johaness vix

    WHY YOU NEVER POST COMPLETE PROJECTS????? this freaking all the beginners on it, almost useless we cannot really get and run!!! respect my time guys please you are make me lose several time on such crap tutorials!

  • Lauri Lubi

    Thanks! You saved my day!

  • Johaness

    this is not so good tutorial sorry but you didnt explain how to use the controllers and directives inside those templates. unfortunately it doesnt works properly.

  • sudheer

    Hello,

    I have an issue with injecting a service into my controller.

    how can i add a factory named pollsFactory with module app.factories into a controller named pollsController with module app.controllers?

    my app.js has both the modules injected.

    and my controllers module has facotories module injected.

    how ever i try to access facotories defined in controller module i get an error for

    Error: [$injector:unpr] http://errors.angularjs.org/1.4.3/$injector/unpr?p0=copeProvider%20%3C-%20%24scope%20%3C-%20pollsFactory

    define([‘./controllers.module.js’], function (controllers) {

    ‘use strict';

    controllers.controller(‘pollsController’, [‘$scope’,’$rootScope’, ‘$timeout’, ‘$state’, ‘pollsFactory’, function ($scope, $rootScope, $timeout, $state, pollsFactory) {

    ….

    ..

    }]);

    });

    • http://startersquad.com/ Dmitry Evseev

      Hi @disqus_og0ruZYFU3:disqus . I see a couple of issues in your examples:
      – on the first screenshot reference to factories is wrong as it’s third dependency, but specified as a second argument;
      – on second screen controllers and factories should be injected as files with the relative paths, e.g. `./contollers`. Otherwise require will see them as named dependencies.

      With these fixed do you still have an issue?

      • sudheer

        thanks for the early reply Dmitry Evseev

        i have paths set in my require.config.js for both controller and services

        ‘controllers': ‘../scripts/controllers/controllers.index’,
        ‘factories': ‘../scripts/factories/factories.index’

        and factories.index.js

        define([
        ‘/scripts/factories/polls.factories.js’
        ], function () {});

        so i dont think that is an issue..

        missed the order of dependency when i posted. i used it as second argument and given as second dependency still no luck..any idea of wat is wrong with the code?

        • http://startersquad.com/ Dmitry Evseev

          Oh, I think it can be the loading part which is missing. Check that pollsFactory file is included into requirejs chains (if you have this file loaded in the network panel). If it’s a part of app.factories then it should listed in its index.js (which is loader).

  • Станислав Катасонов

    hello, how i can use service with resource in controllers?

  • skcin7

    Hello. I am trying to add Satellizer (https://github.com/sahat/satellizer) into my project. I’ve used bower to install Satellizer, and included it into the ‘paths’ array in main.js like so:

    paths: {
    “satellizer”: “vendor/satellizer/satellizer”,
    },

    I’m confused how I exactly get this into the Angular.js app? Whenever I try to inject Satellizer’s $auth service I get an error that says “Unknown provider: $authProvider <- $auth <- LoginCtrl". I know that I need to do some type of configuration/initialization for Angular.js to recognize Satellizer, but I'm not sure how/where to do this.

    I've mostly tried messing around with things in main.js and app.js to try to get Satellizer plugged-in properly to this Angular.js app but nothing I seem to do is working. Thank you for any help you provide.

  • http://www.studio404.net Boštjan Pišler

    Love what you did with the index files :) great idea.

  • Naresh G

    I have implemented this model in my project and it is working fine. However I am facing lot of challenges in concatenating all files with gulp and bring the application up. Is there any example of this model with minification as well?

    • http://startersquad.com/ Dmitry Evseev

      Hello Naresh, yep. Please see an example of the seed project gulp file: https://github.com/StarterSquad/ngseed/blob/develop/Gulpfile.js

      Note that amdOpimize is used instead of requirejs, it supports streams.
      “`

      // JavaScript

      gulp.task(‘js’, function () {

      var amdOptimize = require(‘amd-optimize’);
      var concat = require(‘gulp-concat’);
      var insert = require(‘gulp-insert’);
      var ngAnnotate = require(‘gulp-ng-annotate’);
      var uglify = require(‘gulp-uglify’);
      var config = require(‘./source/js/config-require.js’);

      config.baseUrl = ‘source';

      return gulp.src([‘source/js/main.js’])
      .pipe(plumber(handleError))
      .pipe(amdOptimize(‘js/main’, config))
      .pipe(concat(‘main.js’))
      .pipe(insert.append(‘;require([“js/main”]);’))
      .pipe(ngAnnotate())
      .pipe(uglify())
      .pipe(gulp.dest(‘build/js/’));
      });
      “`

  • lim69

    I dont like that it loads module.js and app.js for fiters, directives, services and controllers.
    It gives lots of files which have same name, someone have better idea to get nice structure and better performance than this one?