Question

I have a directive and a controller. The directive defines a function in its isolate scope. It also references a function in the controller. That function takes a callback. However, when I call it from the directive and pass in a callback, the callback is passed through as undefined. The code below will make this more clear:

Directive

directive('unflagBtn', ["$window", "api",
    function($window, api) {
        return {
            restrict: "E",
            template: "<a ng-click='unflag(config.currentItemId)' class='btn btn-default'>Unflag</a>",
            require: "^DataCtrl",
            scope: {
                config: "=",
                next: "&"
            },
            controller: ["$scope",
                function($scope) {
                    $scope.unflag = function(id) {
                        $scope.next(function() { //this callback does not get passed
                            api.unflag(id, function(result) {
                                //do something
                                return
                            });
                        });
                    };
                }
            ]
        };
    }
]);

Controller

controller('DataCtrl', ['$rootScope', '$scope', 'api', 'dataManager', 'globals',
    function($rootScope, $scope, api, dataManager, globals) {
        ...
        $scope.next = function(cb) { //This function gets called, but the callback is undefined.
            // do something here 
            return cb ? cb() : null;
        };
    }
]);

HTML

<unflag-btn config="config" next="next(cb)"></unflag-btn>

I've read here How to pass argument to method defined in controller but called from directive in Angularjs? that when passing parameters from directives to controller functions, the parameters need to be passed in as objects. So I tried something like this:

$scope.next({cb: function() { //this callback does not get passed still
    api.unflag(id, function(result) {
        //do something
        return
    });
}});

But that did not work. I am not sure if this matters, but I should note that the directive is placed inside a form, which in its place is inside a controller. Just to illustrate the structure:

<controller>
   <form>
        <directive>
   <form>
<controller>

Hope this is clear and thanks in advance!

Was it helpful?

Solution 2

So I unintentionally figured out whats wrong after not being able to pass an object back to the controller as well. What happened, (and what I probably should have mentioned in the question had I known that its relevant) is that the parent scope of this directive unflagbtn is actually the scope of another directive that I have, call it secondDirective. In its turn the secondDirective is getting its scope from "DataCtrl". Simplified code looks like this:

directive("secondDirective", [function(){
    require: "^DataCtrl" // controller
    scope: {
        next: "&" // function that I was trying to call
    }
    ...
    // other code
    ...
}]);

directive("unflagbtn", [function(){
    require: "^DataCtrl" // controller 
    scope: {
        next: "&"
    }, 
    controller: ["$scope", function($scope){
        $scope.unflag = function(){
            $scope.next({cb: {cb: callBackFunctionIWantedToPass}); // this is what worked
        }
    }
}]);

So passing a callback in that manner solved my problem as it made its way back to the controller. This is ugly most likely due to my poor understanding of angular, so I apologize as this is most likely not the correct way to do this, but it solved my problem so I though I'd share.

Cheers,

OTHER TIPS

Try this

        controller: ["$scope",
            function($scope) {
                $scope.unflag = function(id) {
                    $scope.next({
                        cb: function() { //this callback does not get passed
                            api.unflag(id, function(result) {
                                //do something
                                return;
                            });
                        }
                    });
                };
            }
        ]
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top