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

3
  • your success callback says instrumentCodes Commented May 5, 2014 at 16:27
  • Its a typo.. the problem is the same, the code provided here is not a copy/paste Commented May 5, 2014 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. stackoverflow.com/questions/14050195/… Commented May 5, 2014 at 16:48

1 Answer 1

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();
   }
});
Sign up to request clarification or add additional context in comments.

3 Comments

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; //...}
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.
Added some code. See the question posted in the comment above too.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.