0

I'm trying to call a parent controller's function from a custom directive upon choosing an option from a select dropdown, but it keeps giving me ng:cpws error.

Error: [ng:cpws] http://errors.angularjs.org/1.4.8/ng/cpws

HTML:

 <select chosen ng-model="selectedValue.recipientCountry" ng-options="x.Name.toLowerCase() for x in data.RecipientCountries" >
     <option value=""></option>
 </select>

JS:

uiComponentsModule.directive('chosen', [ function () {
return {
    link: function(scope, element, attrs) {
        scope.$watch(function (newVal, oldVal) {
            scope.$parent.selectRecipientCountry(x)
        })
    }
}
}])

I'm trying to modify someone else's code, so it's hard to know exactly what's going on.

Jaeeun Lee
  • 3,056
  • 11
  • 40
  • 60
  • What is "ng:cpws" error? Post error message (or better link). – dfsq Aug 22 '16 at 20:43
  • first argument of `scope.$watch` is the "get" expression which should point to value being watched (or function which return such value). Also x is not defined in `scope.$parent.selectRecipientCountry(x)` – Bartosz Gościński Aug 22 '16 at 20:44

1 Answers1

5

You need to pass the function to the directive from the parent controller, like below (I am free-handing without testing because you didn't provide a plunk, so I am sure you will need to adjust the code. The point is that the function gets passed as a param. If you don't know how to pass variables to directives from the parent controller, you won't understand this, so read up on that first). Note that I added 'scope' to your directive - that's where you define params for your directive, to be passed to the new scope of your directive:

Your directive in the html:

<chosen select-recepient-country = "selectRecipientCountry"></chosen>

Your directive code:

uiComponentsModule.directive('chosen', [ function () {
return {
    scope: {
        selectRecipientCountry: '&selectRecipientCountry',
    },
    link: function(scope, element, attrs) {
        scope.$watch(function (newVal, oldVal) {
            scope.selectRecipientCountry(x)
        })
    }
}
}])

For en explanation, see the article here: http://weblogs.asp.net/dwahlin/creating-custom-angularjs-directives-part-3-isolate-scope-and-function-parameters

You are looking for:

Option 2: Storing a Function Reference and Invoking It

Edit: We have a good example of passing functions here: AngularJS - pass function to directive

Also note that:

    scope: {
        myFunction: '&',
    }

and

    scope: {
        myFunction: '&myFunction',
    }

are equivalent. One just explicitly names the attribute in which it will look for the variable and the other assumes the attribute name will be the same as the scope variable name.

Community
  • 1
  • 1
VSO
  • 11,546
  • 25
  • 99
  • 187
  • this is close but doesn't quite seem to work, I upvoted anyway, because it seems to be correct – Alexander Mills Mar 17 '17 at 01:28
  • 1
    This worked for me. I had a function that was in the parent of my parent controller. The parent controller had access without needing this but the child, surprisingly, did not. Once I added the Option 2 solution, everything works! – Yusif_Nurizade Aug 06 '18 at 01:20