21

I'm trying to call a function passed from a controller's scope into a directive via the "&" operation from the directive's controller. That method, however, is claimed by Angular to be undefined. After reading my code over and over, scouring the internet, and then repeating that process, I've decided to turn to help here.

Here's the relevant part of my controller. It contains the method I pass to my directive.

angular.module('myApp.controllers', []).controller('PostCtrl', ['$scope', 'postalService', function($scope, postalService) {
    $scope.posts = [];

    $scope.getPosts = function() {
        postalService.getPosts(function(err, posts) {
            if(err);
            else $scope.posts = posts;
        });
    };
}]);

Here's my directive. I am unable to invoke onPost.

angular.module('myApp.directives', []).directive('compose', ['postalService', function(postalService) {
    return {
        restrict: 'E',
        transclude: false,
        replace: true,
        scope: {
            onPost: "&" //why will it not
        },
        templateUrl: "partials/components/compose-partial.html",
        controller: function($scope, postalService) {
            $scope.title = "";
            $scope.content = "";
            $scope.newPost = function() {
                postalService.newPost($scope.title, $scope.content, function(err) {
                    if(err) console.log(err + ":(");
                    else {
                        console.log("Success getting posts.");
                        //why can I not invoke onPost()??
                        $scope.onPost();
                    }
                });
            };
        },
    };
}]);

And here's the relevant part of my html

<div ng-controller="PostCtrl">
    <section class="side-bar panel hide-for-small">
        <compose onPost="getPosts()"></compose>
    </section>

    <!--more, non-relevant html here-->

</div>

I know the problem is not with my postalService Service. Instead, the directive reports that no function is passed to it. Why??

1 Answer 1

26

Replace

<compose onPost="getPosts()"></compose>

with

<compose on-post="getPosts()"></compose>

and it'll work.

The Angular docs say why it's so:

Directives have camel cased names such as ngBind. The directive can be invoked by translating the camel case name into snake case with these special characters :, -, or _.

Sign up to request clarification or add additional context in comments.

3 Comments

Ah, of course! Is there any specific reason Angular does that (besides making a bug-tracker rip out his hair)?
@thebradbain I've got no straight answer for that, but most standards that come from W3C tend to use lower case with hyphens, so I'd say the Angular guys just stuck to that convention. I myself don't remember running into any HTML markup written in neither camel case nor pascal case.
HTML is inherently case-insensitive -- attribute onPost is equivalent to attribute onpost. Therefore, a convention of JavaScript camelCase ==> HTML snake-case is reasonable.

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.