0

Getting an error while using require in angular directives.

This is my html:

<!doctype html>

<html ng-app="myApp">
    <head>
        <title>Page Title</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="initial-scale=1.0">
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.4.2/angular-ui-router.js"></script>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
        <script src="app.js"></script>
    </head>

    <body>
        <superman speed>This is a superhero</superman>
    </body>
</html>

My app is:

var myApp=angular.module('myApp',[]);

myApp.directive('superman',function(){

    return{
        restrict:'E',
        controller:function($scope){
            $scope.abilities=[];

            $scope.addspeed=function(){
                $scope.abilities.push('Speed');
            }

        },
        link:function(scope,element,attrs){
            element.bind('mouseenter',function(){
                console.log(scope.abilities);    
            })
        }
    }
})

myApp.directive('speed',function(){
    return {
        require:'superman',
        link:function(scope,element,attrs,supermanCtrl){
            supermanCtrl.addspeed();
        }
    }
})

The error I am getting is supermanCtrl.addspeed() is not a function. I also logged my supermanCtrl and it did not contain addspeed function. Any details why this is happening. Thanks

1 Answer 1

1

The $compile Service injects the this context of the controller as the fourth argument to the linking function. It does not inject the $scope object.

From the Docs:

require

Require another directive and inject its controller as the fourth argument to the linking function.

— AngularJS Comprehensive Directive API Reference (require)

Use the this context of the directive controller to define controller methods:

angular.module("myApp").directive('superman',function(){

    return{
        restrict:'E',
        controller:function($scope){
            $scope.abilities=[];

            $scope.addspeed=function(){
                $scope.abilities.push('Speed');
            }
            //-------------------------------
            //USE `this` context
            this.addspeed = $scope.addspeed;
            //-------------------------------
        },
        link:function(scope,element,attrs){
            element.bind('mouseenter',function(){
                console.log(scope.abilities);    
            })
        }
    }
})
myApp.directive('speed',function(){
    return {
        require:'superman',
        link:function(scope,element,attrs,supermanCtrl){
            supermanCtrl.addspeed();
        }
    }
})

The DEMO on PLNKR


suppose we have large number of functions, so we have to do this.addspeed = $scope.addspeed; everytime. Isn't there any shorter way?

If you don't need the function on $scope, just bind directly to the this property:

angular.module("myApp").directive('superman',function(){

    return{
        restrict:'E',
        controller:function($scope){
            $scope.abilities=[];

            //$scope.addspeed=function(){
            //BIND directly to the `this` property
            this.addspeed = function() {
                $scope.abilities.push('Speed');
            }
        },
        link:function(scope,element,attrs){
            element.bind('mouseenter',function(){
                console.log(scope.abilities);    
            })
        }
    }
})
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, but still one small question, suppose we have large number of functions, so we have to do this.addspeed = $scope.addspeed; everytime. Isn't there any shorter way? Don't know if it makes sense

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.