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

Encountering a problem while creating a Page Object in webdriver.io - getting the error "setValue is not a function" or "cannot read property 'setValue' of undefined"

While working on a webdriver.io automation project, I encountered an issue with recognizing objects in my page object file (login.po.js) when calling them in the test spec file (test.spec.js). The error message displayed is LoginPage.username.setValue is n ...

Having trouble generating a readable output bundle due to the following error message: "The entry module cannot be found: Error: Unable to resolve './src/index.js'"

I'm currently working with Webpack version 6.14.8 within an Asp.net Core Razor Pages project in Visual Studio 2019. My objective is to generate a readable output file, and here's the directory structure I've set up: |-->wwwroot -----> ...

Issue with Vue-Multiselect: Unselecting a group of pre-loaded values is not functioning as expected

My code: https://jsfiddle.net/bgarrison25/tndsmkq1/4/ Html: <div id="app"> <label class="typo__label">Groups</label> <multiselect v-model="value" :options="options" :multiple="true" group-values="libs" g ...

Convert a number to binary in JavaScript, but display the result as infinity

data = parseInt(num); bin =0; pow=1; var rem=0 ; while(data != 0){ rem = data % 2; data = data / 2; bin = rem * pow + bin; pow = pow *10; } document.write(bin); I encountered an issue with my JavaScript code. Even though the example should output 11011 ...

Retrieve a specific object from a JSON array nested within an array of objects, by utilizing a PHP script

There are two JSON files that contain JSON objects, with one of the files containing an array of objects within another array of objects. The first file is orders.json: { "orders": [ { "address": null, ...

Testing controls in AngularJS is an essential part of verifying the

Just diving into the world of Angular and wanting to write some basic unit tests for my controllers, here is what I have so far. app.js: 'use strict'; // Define the main module along with its dependencies angular.module('Prototype', ...

Utilizing ng-repeat in a tabset to create an interactive and customizable tab interface

I am using angular ui tab (angular-ui.github.io/bootstrap/) and I expected that with ng-repeat, I would be able to make it dynamic, meaning the user can add tabs. However, unexpectedly it duplicates the tabs. Here is a demo: http://plnkr.co/edit/iHi1aOfbz ...

Is there a way to send the image's name as a parameter?

I am facing a challenge in achieving a specific task and need some guidance. My current approach involves passing the image name as a parameter to the cancelimage.php script, but it seems like I am not utilizing the variable 'image_file_name' cor ...

Synchronizing Ionic Data Between Screen and Controller

I am new to the Ionic framework and encountering a data synchronization issue. The problem occurs when the interface calls a function on the controller, which removes an item from an array called lupulos. This array is linked with Angular's ng-repeat= ...

Capture an image of the element

Hi there, I'm currently attempting to use PhantomJS to capture a screenshot of a specific element. I'm utilizing the PhantomJS bridge for Node.js: phantom Here's what I have so far: page.includeJs('http://ajax.googleapis.com/ajax/libs ...

Utilize the parsing functionality in three.js to extract JSON geometry data

After exporting a model from Blender using the three.js exporter and successfully loading it with the JSONLoader, my next challenge is to store the JSON information in a variable and parse it to display the model without having to load an external file. T ...

"Using the power of jQuery to efficiently bind events to elements through associative

I am attempting to link the same action to 3 checkboxes, with a different outcome for each: var checkboxes = { 'option1' : 'result1', 'option2' : 'result2', 'option3' : 'result3', }; ...

Exploring React hook functionalities can lead to discovering unexpected issues such as cyclic dependencies on location.hash when

My implementation of a useEffect involves reading the location.hash and adjusting the hash based on certain dependencies. Here is a snippet of how it works: useEffect(() => { const hashAlreadyPresent = () => { const hashArr = history.locati ...

Is it feasible to invert the order of arguments in async.apply?

According to the async documentation: apply(function, arguments..) Creates a function continuation with certain arguments already applied. This can be useful when combined with other control flow functions. Any additional arguments passed to the returned ...

What is the best way to flip the direction of the text input for a Calculator?

I am currently working on creating a basic calculator from scratch using HTML, CSS, and JavaScript. I have been trying to figure out how to align the numbers to the right side of the input element. Can anyone provide me with guidance on how to achieve thi ...

Invoke PHP by clicking on a button

I am facing an issue with a button I have created. Here is the code for it: <input type="submit" name="kudos_button" value="★ Give kudos"/>' To test it, I wrote a PHP script like this below the </html> tag: ...

What is the method to retrieve the selected value from a drop-down menu that is connected to JSON keys?

I am just starting to learn AngularJS and I need help with binding column names (keys from key-value pairs) to a select list. I want to be able to retrieve the key name when the selection in the select list is changed. The select list displays: name, snip ...

Encountering TypeError while attempting to assign an axios response to a data variable within a Vue component

Encountering the error message TypeError: Cannot set property 'randomWord' of undefined specifically at the line: this.randomWord = response.data.word; Confirming that console.log(response.data.word) does display a string. Vue Component Structu ...

Securing API Keys in AngularJS and NodeJS applications and managing them for deployment on Git and Heroku

I'm currently working on a project that involves using API keys in my AngularJS and NodeJS files. My main concern is keeping these keys secure while also being able to push my application files to Git and Heroku without exposing them to the public. I& ...

Unable to invoke JS function in Drupal 5 file

In my current project using Drupal 5, I have a specific .js file that is included using the code: drupal_add_js(drupal_get_path('module','MTM')."/include/JS_form.js"); Additionally, there is an element on the page: <a onclick="MTM ...