$apply already in progress when sending a click event to a button?
Asked Answered
L

1

19

I have a button on my page with an id="viewQuestions" on a page:

    <body ng-keydown="key($event);">

My code is checking for key hits like this:

    $scope.key = function ($event) {
        $scope.$broadcast('key', $event.keyCode)
    }

and in the controller:

 $scope.$on('key', function (e, key) {
        if (key == 13) {
            if (ts.test.current && ts.test.userTestId) {
                document.getElementById("viewQuestions").click();
            }               
        }
    });

When I run the code and click ENTER then I get this error:

 Error: [$rootScope:inprog] $apply already in progress
http://errors.angularjs.org/1.3.7/$rootScope/inprog?p0=%24apply
    at REGEX_STRING_REGEXP (http://localhost:2757/lib/angular/angular.js:63:12)
    at beginPhase (http://localhost:2757/lib/angular/angular.js:14735:15)
    at Scope.$get.Scope.$apply (http://localhost:2757/lib/angular/angular.js:14479:11)
    at HTMLButtonElement.<anonymous> (http://localhost:2757/lib/angular/angular.js:22945:23)
    at HTMLButtonElement.eventHandler (http://localhost:2757/lib/angular/angular.js:3009:21)
    at http://localhost:2757/app/tests/controllers/TestsController.js:24:62
    at Scope.$get.Scope.$broadcast (http://localhost:2757/lib/angular/angular.js:14700:28)
    at Scope.AppController.$scope.key (http://localhost:2757/app/appController.js:30:20)
    at $parseFunctionCall (http://localhost:2757/lib/angular/angular.js:12330:18)
    at ngEventDirectives.(anonymous function).compile.element.on.callback (http://localhost:2757/lib/angular/angular.js:22940:17)

Can anyone give me advice on this. I just want to simulate the clicking of a button when the ENTER key is pressed. I did try solutions with forms but it does not meet my rather complicated needs.

Lola answered 12/3, 2015 at 11:16 Comment(2)
Try this, <button class="btn" id="abc" ng-click="functionName()">Example</button> and define that function on the angular scope as $scope . functionName = function() {}Flightless
Sorry but what I want to do is to have the user be able to see the button changed to the clicked state and back. Ashad's solution does this but it does not work when the click of the button is initiated by another event like a keypress.Lola
H
38

Your click event is running digest cycle which is conflicting with current digest cycle, $timeout would help you in this situation. Wrap click event inside $timeout function.

Markup

<body ng-app="myApp" ng-controller="testCtrl" ng-keydown="key($event);">
    <button id="viewQuestions" type="button" ng-click="isButtonClicked = !isButtonClicked; test();"> Test</button>
    Is Button Clicked {{isButtonClicked}}
</body>

Code

$scope.$on('key', function (e, key) {
    if (key == 13) {
        if (ts.test.current && ts.test.userTestId) {
            $timeout(function(){
                angular.element(document.getElementById("viewQuestions")).trigger('click');
            })
        }               
    }
});

Whatever you write inside ng-click will get called.

Working Fiddle

Hexastich answered 14/3, 2015 at 17:9 Comment(2)
I cant since is not my question.Braid
$timeout for zero milliseconds worked like a charm. Thanks!Thomism

© 2022 - 2024 — McMap. All rights reserved.