Implementing ng-if with asynchronous functions: A step-by-step guide

The objective here is to display an image in a template only if the ratio of its dimensions is greater than 2.

<img class="main-img" ng-if="showImage($index)" ng-src="{{item.img}}">

Implementation:

$scope.showImage = function(index) {
    var img = new Image();
    img.src = $scope.items[index].img;
    img.addEventListener("load", function() {
        var ratio = this.naturalWidth / this.naturalHeight;
        if (ratio > 2) {
            return true;
        } else {
            return false;
        }
    })
}

The issue here is that ng-if does not wait for the image to finish loading. Any suggestions on how to resolve this? Thank you.

Answer №1

If you include $scope.$apply() at the conclusion of your function, Angular will be prompted to load the images.

$scope.showImage = function(index) {
  var img = new Image();
  img.src = $scope.items[index].img;
  img.addEventListener("load", function() {
      var ratio = this.naturalWidth / this.naturalHeight;
      if (ratio > 2) {
          return true;
      } else {
          return false;
      }
   })
  $scope.apply()
}

Answer №2

<img class="main-img" ng-init="displayImage($index)" ng-if="loadImage" ng-src="{{item.img}}">

$scope.loadImage=false;
$scope.displayImage = function(index) {
    var img = new Image();
    img.src = $scope.items[index].img;
    img.addEventListener("load", function() {
        var aspectRatio = this.naturalWidth / this.naturalHeight;
        if (aspectRatio > 2) {
            $scope.loadImage=true;
            return true;
        } else {
            return false;
        }
    })
}

Revise to the following format:

Answer №3

After reviewing the code mentioned above, it appears that using 'ng-init' instead of 'ng-if' would be more appropriate. If you wrap the code with ng-repeat, none of the images will be displayed based on the function provided. Additionally, consider setting a timeout for better execution.

Answer №4

It appears that these events are occurring outside of Angular's digest cycle. While $apply may solve the issue, another option is to eliminate the event listener and instead bind to a function that returns false until the required attributes are present. However, this approach can be resource-intensive. Another solution would be to place the load event/listener on the image within a directive, allowing you to either call a $scope method or use $broadcast to manage the flag for ng-if. For more information, you can check out this example: Image loaded event in for ng-src in AngularJS

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

Kendo's data-bind onclick feature functions properly on web browsers but fails to work on mobile devices

As a newcomer to Kendo and JavaScript, I may be missing something obvious... In one of my list entries, I have a simple call like this: <li style="margin: 0.5em 0 0.5em 0"> <a href="#transaction-details" data-bind="click: onB ...

Contrasting createMuiTheme and getMuiTheme

When would you choose to use one over the other? What are the key differences in how they operate? ...

Manipulate your table data with jQuery: add, update, delete, and display information with ease

When adding data dynamically to the table and attempting to edit, the checkbox value is not updating. This issue needs to be resolved. You can view the code in action on jsFiddle here on JSFiddle ...

Tips for obtaining user input to place markers on a video timeline with JavaScript

I am new to Java script and I am trying to create a video player where users can click on the progress bar to place markers. Can you please review my code below and let me know if there are any errors? index.html <!doctype html> <html> <he ...

Ajax handling all tasks except for adding HTML elements

Having an issue with my basic "Load More on Scroll" AJAX function. The console is showing that the HTML is being sent back from the request, but for some reason, nothing is being rendered on the page. I must be missing something really simple here. $(wi ...

Utilizing a Jasmine server in standalone mode for testing AngularJS factories

I have been diving into the world of AngularJS testing by using a stand-alone jasmine server. While I was able to successfully test a controller, I ran into some issues when trying to test a factory that I had created. The error message I encountered was: ...

Looking for a script that automatically swaps out a div at set intervals? You'll need to tweak it so that it only

I created a js script that dynamically changes the content of certain div elements at specified intervals. While I appreciate how it functions, I now need to modify it so that the script only executes once. Can someone help me achieve this? <script typ ...

Angular login/signup modal/dialog component for seamless user authentication

Currently, I am working on adding a login/signin dialog to my app similar to the one used by Medium. After doing extensive research online, I have decided to use the $modal from angular ui-bootstrap for this. Can anyone please recommend a tutorial that wil ...

Fixing the Dropdown in AngularJS: A Step-by-Step Guide

Having trouble implementing a dropdown with search functionality in AngularJS. The issue I'm facing is that the dropdown menu is not displaying correctly after applying the filter for search. Instead of a traditional dropdown appearance, it seems to ...

When attempting to access http://localhost:3000/traceur in Angular 2 with the angular-in-memory-web-api, a 404 (Not Found) error

Hello, I'm encountering an issue with angular-in-memory-web-api. I have attempted to use angular2-in-memory-web-api in SystemJS and other solutions, but without success. I am currently using the official quickstart template. Thank you for any assistan ...

When using Jquery, hovering over an element will cause the full title to be

I have created a toggle div that displays an ellipsis (...) when the long title is longer than 30 characters. Now, I want the full text of the long title to appear when hovering over the div. Check out this JS Fiddle for reference. JS $('#popu ...

Connecting two sets of data from a mongoDB database using vue.js

Hey there, I'm a newcomer to vue and mongodb. I've set up two collections - one for storing user details and the other for business details. When a business registers through a form, their information is saved in mongodb. Now, I've created a ...

Is there a way to create a reusable HTTP response handler for Node.js applications?

As I work on creating a rest api for a node application, I often find myself repeating the same code structure: function(req, res, next) { databaseCall() .then( (results) => { if (results != null) { res.status(200).send(results); } el ...

Why does this switch case statement fail to effectively replace the elements of the text in order to unravel this JavaScript problem?

Question I need help converting special characters to HTML entities in a string: &, <, >, " (double quote), and ' (apostrophe). My Code function convertHTML(str) { let tempArr = ['a']; let newArr = []; let regex ...

Exploring alternative methods of iterating over the values in a key-value pair within an AngularJS framework

My key-value pair consists of a long list of file names stored in the variable $ctrl.displayData- 143:"/this/is/a/very/long/fil22↵/this/is/a/very/long/file/path.php↵anotherone.php↵newfilel123.php" When I use ng-repeat to display these file names, t ...

Browsing a container with JavaScript

I am attempting to display one div at a time and scroll through them repeatedly. I found and modified a Fiddle that works as intended, but when I try to implement it on my own test page, the divs do not scroll as expected. Here is the Fiddle example: http ...

Is it advisable to implement the modular pattern when creating a Node.js module?

These days, it's quite common to utilize the modular pattern when coding in JavaScript for web development. However, I've noticed that nodejs modules distributed on npm often do not follow this approach. Is there a specific reason why nodejs diff ...

JavaScript rearrange array elements

Currently, I'm attempting to move the values of an array over by a random amount. For instance: var array = [1,2,3,4]; var shiftAmount = 1; The goal is to shift the array so that it looks like [4,1,2,3] ...

Increase the detection range in empty lists for Vue-draggable-next

I am currently utilizing Vue-draggable-next in conjunction with Vue 3 to enable draggable lists within my application. In certain scenarios, users need to drag items from other lists into lists that are initially empty. I have noticed that the area for det ...

AngularJS: Issue with $watch not triggering when changed in child scope

Here is the scenario I am facing: Within my parent scope, I have created an object named rule, which has an attribute called "keyword". A watcher is set on this keyword as follows: $scope.$watch("rule.keyword", function(newKeyword){...}); However, when t ...