While attempting to use $scope.$apply() in Angular, I encountered a bug that

I have set up a specific example in a jsbin: http://jsbin.com/deqerelita/1/

Situation The concept is quite straightforward. You click a button, the controller adds to the model, and the view updates accordingly with a hidden input type="file". After the view is updated, the controller clicks the last file input added.

Issue When the controller clicks the file input before running $scope.$apply() nothing happens until the second click, presumably because Angular has not yet registered the new input. When I run $scope.$apply(), the console throws errors but does successfully click the input.

HTML Code:

  <div ng-controller="fileButtons">
    <input type="button" ng-click="handleImage.add()" value="add another file button"/>

    <div class="imageUploadPreviewContainer">
        <div class="imageUploadPreview hide" data-ng-repeat="file in files" file-index="{{$index}}">
            <input type="file" class="hide"/>
        </div>
    </div>
  </div>

</div></div>

Angular JS Code:

 var myApp = angular.module('myApp', []);
myApp.controller('fileButtons', ['$scope', '$log',
    function($scope, $log){
        $scope.files = [];
        $scope.handleImage = {
            add: function(){
              $scope.files.push({
                state : 'started'
              });
              $log.log('added');
              $scope.$apply(); 
              angular.element('.imageUploadPreviewContainer .imageUploadPreview:last input[type=file]').trigger('click')
            }
        }
    }
]);

New to Angular, so please excuse any amateurish design flaws

Answer №1

When using $scope.$apply(), it triggers a $digest. In angular, there can only be one ongoing $digest or $apply operation at any given time.

To work around this limitation, consider utilizing $timeout

 $timeout(function(){
   angular.element('.imageUploadPreviewContainer .imageUploadPreview:last input[type=file]').trigger('click')
 }, 0) 

Note: Ensure to inject $timeout in your controller.

Answer №2

If I were to implement a delay in my AngularJS application, I would utilize the $timeout method.

var myApp = angular.module('myApp', []);
myApp.controller('fileButtons', ['$scope', '$log','$timeout', function($scope, $log, $timeout)
{
    $scope.files = [];
    $scope.handleImage = {
      add: function()
      {
        $scope.files.push({state : 'started'});
        $log.log('added');
        $timeout(function()
        {
          angular.element('.imageUploadPreviewContainer .imageUploadPreview:last input[type=file]').trigger('click')
        },0);
      }
    };
  }
]);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Component fails to update when attribute is modified

My issue is that the crud-table component does not refresh when I change currentTable. It works when I assign currentTable = 'doctor' in the created() hook, but not here. Why is that? <template> <div id="adminpanel"> <div id ...

Error: Module not found - Unable to locate 'dropzone'

Since migrating from Angular 4.4 to Angular 8.0, I encountered the following issue: ERROR in ./src/attributes/import/import.component.ts Module not found: Error: Can't resolve 'dropzone' in 'C:....\src\attributes\imp ...

Embedding an Iframe in Angular 2 directly from the database

Looking for assistance with iframes in Angular 2. Initially, embedding an iframe directly into a component's template functions correctly. <iframe src='http://plnkr.co/edit/zZ0BgJHvQl5CfrZZ5kzg?p=preview | safeUrl' allowtransp ...

What is the jQuery alternative for the classList property in vanilla JavaScript?

Currently, I am working on a collaborative project with two acquaintances. One of the requirements is to stick to either vanilla JavaScript selectors like document.getElementById("thisDiv"); or jQuery selectors such as $("#thisDiv"); to maintain consis ...

Is it possible to extract tooltip text from a website using Python and Selenium, specifically when the text is generated by JavaScript?

Can anyone help me retrieve the tooltip text that appears when I hover over the time indicating how long ago a game was played? You can find my summoner profile here. I have noticed that the tooltip text is not visible in the HTML code and suspect it may ...

What is the best way to continuously add items to a div until their heights are equal?

In my layout, I have two divs positioned next to each other. Typically, the left div displays n+2 items while the right div displays n items. The value of n changes depending on the category and is already set. However, there are instances where certain ...

Deciphering the LocalDate and nested object array in an AJAX response

Seeking assistance, looking for solutions to two problems. Firstly, how can I display LocalDate in an ajax response? And secondly, how do I iterate over a list of Custom objects received in the ajax response? I am passing a List of Custom Objects and Loca ...

A Simple Guide to Setting a Background Image in React Native with the Nativebase.io Library

What is the process for including a background image in React Native with the help of the Nativebase.io Library? I have a specific screen where I need to incorporate a background image, with all other elements positioned at the center of the image. ...

"Facing an issue with Google Chrome not refreshing the latest options in an HTML select dropdown list

Having trouble creating an offline HTML file that incorporates jQuery for the script. The page features a state select menu followed by a second menu for counties. When a state is selected, only the corresponding counties should display while others remai ...

Bootstrapvalidator does not function properly with select2.js

My code is not validating the select field. What could be causing this issue? Can anyone provide a solution? Apologies for my poor English, and thank you in advance for your response. Here is my form: <form name="form_tambah" class="form_tambah"> ...

Is there a way to efficiently add delimiters to an array using jquery dynamically?

Just joined this community and still figuring things out. I have a question - how can I use jQuery to dynamically add a delimiter like "|" after every 3 elements in an array? This way, I can explode the array and utilize the resulting arrays separately. He ...

Guide on incorporating Activiti into an AngularJS application

Looking for guidance on implementing business process management in application development using AngularJS and REST. After researching, the options I found are Activiti, Camunda and BonitaBPM. Does anyone have experience with these tools? Any recommendat ...

What causes variables and functions to behave differently when it comes to hoisting?

I've recently been delving into some documentation and have noticed some inconsistencies in hoisting patterns within JavaScript. Consider the following examples: When it comes to functions, function abc(){ console.log("worked") } abc(); OUTPUT : ...

Error: Trying to play the Snake Game with the P5.js Library, but getting the message "(X)

During my journey of coding a snake game by following a tutorial, I encountered an issue that the instructor had not faced before. Strangely enough, I am unable to identify the root cause of this problem. To aid in troubleshooting, I meticulously commente ...

What is the best way to update JSON data using JQuery?

I apologize for posing a seemingly simple query, but my understanding of JavaScript and JQuery is still in its early stages. The predicament I currently face involves retrieving JSON data from an external server where the information undergoes frequent ch ...

Trying to configure and use two joysticks at the same time using touch events

I have been grappling with this problem for the past two days. My current project involves using an HTML5/JS game engine called ImpactJS, and I came across a helpful plugin designed to create joystick touch zones for mobile devices. The basic concept is th ...

Submitting the form does not result in the textbox being cleared

I have been attempting to clear the txtSubTotal text box upon clicking the PROCEED button, but it seems that my efforts have been in vain despite trying various code examples, including those from SO. btnProceed/HTML <input type="submit" name="btnProc ...

Topaz font does not properly display backslashes and certain characters when rendered on Canvas

Who would have thought I'd stumble upon a new challenge on Stack Overflow? But here we are. If there's already a solution out there, please guide me in the right direction. I'm currently developing an interactive desktop environment inspired ...

Complete loading of iframe content on Internet Explorer versions 8 and 9

Having an issue with the full loading of a page in IE8-9. I need to perform certain actions after the content within a div is fully loaded, but it seems that in IE8-9, the page fails to load completely. This is causing problems as my actions are dependent ...

Delete an item from an array based on its index within the props

I am attempting to remove a specific value by its index in the props array that was passed from another component. const updatedData = [...this.props.data].splice([...this.props.data].indexOf(oldData), 1); const {tableData, ...application} = oldData; this ...