1

I have an interesting situation, which I fully admit I may not be handling correctly.

I want to load directives in to an Angular app using AngularAMD, but the information on the directives is coming from a database/API call. Here's how I'm handing it at the moment:

app.run(function ($rootScope, $state, $http) {
    $rootScope.$state = $state;
    $rootScope.rootPages = JSON.parse(localStorage.pages);

    $http.get('api/Directives').then(function (resp) {
        for (var i = 0; i < resp.data.length; i++) {
            var dirInfo = resp.data[i];
            var dirConfig = JSON.parse(dirInfo.Configuration);

            angularAMD.directive(dirInfo.Name, function () {
                return {
                    restrict: 'E',
                    controller: eval(dirConfig.controller),
                    templateUrl: dirConfig.templateUrl,
                    scope: true,
                }
            });
        }
    }, function (error) {
        alert('error');
    });
});

At the moment this generates two directives, and I have two links on my page, one for each module (using angular-ui-router and router-ui-extras to load those based on another database table/API call). Theoretically clicking link 1 should bring up directive 1, and link 2 should bring up directive 2. However, when I click link 1, directive 2 comes up. It's almost as if the only directive that registers is directive 2. Here's the information I get from the database:

dirInfo1: {
    Name: directiveOne,
    templateUrl: /html/directiveOne.html,
    controller: controllerOne
}

dirInfo2: {
    Name: directiveTwo,
    templateUrl: /html/directiveTwo.html,
    controller: controllerTwo
}    

In this case, only directiveTwo.html is shown, and only controllerTwo fires.

Any help would be greatly appreciated.

1 Answers1

0

It't a usual problem using for loop with delayed/async operations. By the moment that first angularAMD.directive is resolved var dirInfo = resp.data[i]; inside of the loop is is equal to the last item in the list.

You need to use either Promises or anonymous function inside of a loop to keep the link to a right index inside of async function. Check simple example of what's happening in your case here: https://stackoverflow.com/a/13977142/405623

for ( i = 0; i < items.length; i++) {
  (function(thisItem) {
    setTimeout(function() {
     console.log(thisItem);
    }, i * 1000);
  )(items[i]);
}
Community
  • 1
  • 1
shershen
  • 9,875
  • 11
  • 39
  • 60
  • So basically I ended up wrapping the inside of the loop in a promise, and it now does exactly what I need it to go. Thank you very much! – psywildfire May 20 '16 at 14:55