1

When $scope.instrumentNames is setting inside the controller like on the code provided it works

When $scope.instrumentNames is setting in the HTTP success function it doesn't work

The data returned by the http function IS an Array.

Console.log(data)//["Guitar", "Bass", "Violin"]
Console.log($scope.instrumentNames) //["Guitar", "Bass", "Violin"]

Controller

app.controller("PrivateProfileController",
    ["$scope", "$http", "$routeParams",  function( $scope, $http, $routeParams ) {

        $scope.instrumentNames = ["Guitar", "Bass", "Violin"];//WORKING !

        function loadInstrumentNames(){
            $http({
                url: '/Instrument/getInstrumentsName',
                method: "GET"
            }).success(function(data){
                //data = ["Guitar", "Bass", "Violin"]
                $scope.instrumentNames = data;//NOT WORKING 
            });
        }

        loadInstrumentNames()
    }]
);

Directive

app.directive('autoComplete', [function($timeout) {
    return    {
        restrict: "A",
        link : function(scope, element, attrs) {
            element.autocomplete({
                source: scope[attrs.uiItems],
                select: function() {
                    $timeout(function() {
                      element.trigger('input');
                    }, 200);
                }
            });
        }
    };
}]);

Template

<input auto-complete ui-items="instrumentNames">

It's like the directive is called before the http success is finished. Im stuck with this problem and any help or suggestion would be very appreciated!

Thanks

Merlin
  • 4,907
  • 2
  • 33
  • 51
  • your success callback says `instrumentCodes` – adrichman May 05 '14 at 16:27
  • Its a typo.. the problem is the same, the code provided here is not a copy/paste – Merlin May 05 '14 at 16:34
  • the issue is likely the directive reading from the scope _before_ your request has completed. Your directive needs to be binding to the parent scope and checking for changes on that. http://stackoverflow.com/questions/14050195/what-is-the-difference-between-and-in-directive-scope – thescientist May 05 '14 at 16:48

1 Answers1

2

It's like the directive is called before the http success is finished.

I'm sure this is exactly what is happening. After the request to /Instrument/getInstrumentsName has been made, and before the response, the directive code will run. When the link function runs, scope[attrs.uiItems] will be undefined. You need to wait until the data comes back before doing the autocomplete call.

This can be done with a $watch. Something like this:

app.directive('autoComplete', [function($timeout) {
    return    {
        restrict: "A",
        link : function(scope, element, attrs) {
            scope.$watch(attrs.uiItems, function(uiItems) {
                if (uiItems) {
                    element.autocomplete({
                        source: scope[attrs.uiItems],
                        select: function() {
                            $timeout(function() {
                              element.trigger('input');
                            }, 200);
                        }
                    });
                }
            });
        }
    };
}]);

You probably only want that to run once, so you can set a var equal to that $watch call, which returns a deregistering function. Call that function at the end, and it won't run the $watch anymore.

var unwatch = scope.$watch(attrs.uiItems, function(uiItems) {
   if (uiItems) {
       //everything you want to do with the data
       unwatch();
   }
});
dnc253
  • 39,967
  • 41
  • 141
  • 157
  • Perfect it is working! thanks ! Just don't totally understand what your saying about calling the function at the end. Could you provide some code ?? Is it something like var checked = false; if (uiItems && !checked){checked = true; //...} – Merlin May 05 '14 at 16:57
  • http://stackoverflow.com/questions/14957614/angular-js-clear-watch - see the answer to this question. If you use var listener = $scope.$watch etc then if you call that function via listener() it will automatically deregister the $watch. – Michael May 05 '14 at 16:59
  • Added some code. See the question posted in the comment above too. – dnc253 May 05 '14 at 17:02