CodeVirtuoso CodeVirtuoso - 10 days ago 5
AngularJS Question

AngularJS Directive element method binding - TypeError: Cannot use 'in' operator to search for 'functionName' in 1

This is the controller of the main template:

app.controller('OverviewCtrl', ['$scope', '$location', '$routeParams', 'websiteService', 'helperService', function($scope, $location, $routeParams, websiteService, helperService) {
...
$scope.editWebsite = function(id) {
$location.path('/websites/edit/' + id);
};
}]);


This is the directive:

app.directive('wdaWebsitesOverview', function() {
return {
restrict: 'E',
scope: {
heading: '=',
websites: '=',
editWebsite: '&'
},
templateUrl: 'views/websites-overview.html'
}
});


This is how the directive is applied in main template:

<wda-websites-overview heading="'All websites'" websites="websites" edit-website="editWebsite(id)"></wda-websites-overview>


and this is method is called from directive template (website-overview.html):

<td data-ng-click="editWebsite(website.id)">EDIT</td>


QUESTION: When EDIT is clicked, this error appears in the console:


TypeError: Cannot use 'in' operator to search for 'editWebsite' in 1


Does anyone know what goes on here?

Answer

Since you defined an expression binding (&), you need to explicitely call it with a JSON containing the id if you want to bind it in the HTML as edit-website="editWebsite(id)".

Indeed, Angular need to understand what this id is in your HTML, and since it is not part of your scope, you need to add what are called "locals" to your call by doing:

data-ng-click="editWebsite({id: website.id})"

Or as an alternative:

data-ng-click="onClick(website.id)"

With the controller/link code:

$scope.onClick = function(id) {
  // Ad "id" to the locals of "editWebsite" 
  $scope.editWebsite({id: id});
}

This is documented here, look for the example involving "close({message: 'closing for now'})"

https://docs.angularjs.org/guide/directive