AngularJS - ng-style fails to dynamically update the CSS background property

There's a service I'm using that returns image URLs, and I call it with the following code:

angular.forEach(results, function (item) {
     item.img = "/images/searchItem.jpg";
     $http.post("https://my.api.com/?id=" + item.id).success(
           function (url) {
               item.img = url;
           });
});

Previously, I displayed the image using ng-src attribute in my view like this:

<img  ng-src="{{item.img}}">

Recently, I decided to use background-image on a SPAN instead:

<span ng-style="{'background':'transparent url({{item.img}})'}"></span>

Now, the flow only works correctly on the first run. After that, despite seeing updated HTML in the console like this:

<span ng-style="{'background':'transparent url(http://expertsimages.liveperson.com/images/rating/rate10.gif)'}" style="background-image: url(https://fb.lp-chat.com/images/searchItem.jpg); background-color: transparent; background-position: initial initial; background-repeat: initial initial;"></span>

the actual HTML remains in its initial state.

I've attempted calling apply/digest on post success, but received a $digest already in progress error (which is understandable). Strangely, after a normal digest cycle triggered by other UI changes, the correct image does appear.

What could be causing this issue?

Update: I've put together a JS fiddle to showcase this problem...it seems like it might be an Angular bug.

Answer №1

I encountered a similar issue and found a solution. Instead of using {{ }} for evaluation, opt for string + value concatenation.

Try this approach:

<span ng-style="{'background':'transparent url(' + item.img + ')'}"></span>)

Check out the updated version of your online demo

Answer №2

The issue arises because angular only evaluates the content of single brackets once and cannot find the variable you want to bind within that string.

One solution is to create a custom directive like this:

app.directive('backImg', function(){
    return function(scope, element, attrs){
        attrs.$observe('backImg', function(value) {
            element.css({
                'background': 'transparent url(' + value +')'
            });
        });
    };
});

You can then use it in your template as follows:

<div ng-if="vis" class="container" back-img="{{imgSrc}}"></div>

I have made changes to your fiddle and it appears to be working correctly http://jsfiddle.net/dS4pB/3/

Answer №3

To ensure smooth updating of your scope variable, consider encapsulating the update within a $timeout function. This way, the updates will be applied to your scope and view without causing any conflicts with an ongoing digest cycle:

    $timeout(function(){
        $scope.var = value;
    });

For more insights on the difference between using apply and timeout, check out this informative thread.

Answer №4

If you're currently experiencing a similar issue to what I recently resolved by using ng-bind, take a look at the solution provided in this particular question:

Why is ng-bind preferred over {{}} in AngularJS?

Since implementing ng-bind, I've noticed significant improvements in how my innerHTML gets updated.

Answer №5

Angular 2 offers a unique approach to achieve this, using [style.*]="value"

<span [style.background-color]="transparent" [style.background-image]="item.img"></span>

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

Guide on detecting errors when parameters are not provided with req.params in Node.js

My question revolves around a piece of code that I have been working on. Here is the snippet: const express = require('express') const app = express() app.get('/test/:name', (req, res) => { const {name} = req.params; res.send(`P ...

My app.js failed to launch on Heroku, receiving a Code H10 status 503 error

Starting with some screenshots: https://i.sstatic.net/E0pyj.png https://i.sstatic.net/SkZDv.png https://i.sstatic.net/HJ3Iw.png https://i.sstatic.net/LKFv2.png The full error log is below: 2020-06-15T10:46:45.640400+00:00 heroku[web.1]: Starting pro ...

My Node.Js app refuses to run using my computer's IP address, yet works perfectly with localhost

My Node.js application is set up to listen on port 5050 of my machine: Visiting http://localhost:5050/myapp loads the app successfully. I am using the Express framework, so my listening framework looks like this: var server = app.listen(5050, '0.0.0 ...

Is there a way to execute React JS functions within a webview using my Android code?

Currently, I am dealing with a React-Typescript webapp that is being hosted in a WebView within my Android application. My main goal is to transfer data from the Android client to the Webview. However, this task becomes more complex due to the fact that i ...

import shaders from next.js

In my web app built with next.js, I am utilizing WebGL to render a 2D scene. Currently, I have my fragment and vertex shaders hardcoded as strings in my JavaScript: var fragmentShaderSource = [ ` #ifdef GL_ES`, `precision highp float;`, ` #en ...

Generate a random number not found within the given array

Hopefully, I can explain this clearly. Imagine I have 8 boxes with the class .boxA, each containing a numeric value generated from JavaScript: <div class="tfooter"> <div class="boxA" id="bx3" value="3">3</div> <div class="box ...

Customize Color of Bootstrap Tooltips

Is there a way to customize the appearance of BootStrap tooltips by changing the color and aligning the text to the left? I've tried various CSS modifications from different posts, but none seem to work. Any idea on how to alter the CSS of the tooltip ...

Update the bootstrap navigation bar

I'm currently using bootstrap to construct my website. The navbar I have is quite typical with menu options, but I am aiming to modify the CSS in order to achieve a design similar to the image provided below (this design should be responsive and funct ...

Mobile Devices and Local Storage: What You Need to Know for Safe and Efficient Use. Looking for advice from experienced developers

Need help with caching user input on an Angular11 + Firebase app? Let's discuss implementing a caching feature for a dynamic form section that can contain varying fields based on the use case. The goal is to save user input in LocalStorage to ensure ...

The background-size:cover property fails to function properly on iPhone models 4 and 5

I have taken on the task of educating my younger sister about programming, and we collaborated on creating this project together. Nicki Minaj Website However, we encountered an issue where the background image does not fully cover the screen when using b ...

Cannot open file upload upon clicking the LinkButton

I am attempting to utilize a jQuery function to open the file upload control. Code in the head section of the page <script type="text/javascript" src="http://code.jquery.com/jquery-1.8.2.js"></script> <script type="text/javascript"> ...

Having trouble transmitting data from the View to the Controller

Need help with this issue. I'm having trouble passing my data to the controller. Below is my ajax code. <script type="text/javascript"> $(document).on("click", "#login_button", function () { var userName = document.getElementById(" ...

AngularJS allows you to add a required attribute to an input tag, which will

When incorporating the required field or email validation on the input tag in AngularJS, a tooltip appears. I am looking to eliminate this tooltip while utilizing Bootstrap. Any suggestions on how to achieve this? ...

Normal version with background image and mobile version with background color

Seeking advice on how to optimize my website for mobile devices. I have two separate CSS files - one for the mobile version and one for the desktop version. Combining them in the head of my HTML file is causing issues, as the background style from the desk ...

Hey there, I'm having trouble with button B. It's not working, do

Why doesn't my Button B display an alert popup? Here are the code snippets from separate files: .html: <html> <body> <input type="button" class="popup" value="BUTTON A"/><br> <input type="button" class="displaymeh ...

Synchronize information from CouchDB to PouchDB in order to enable offline storage on a Windows 7 system through the utilization of Google Chrome version

My goal is to sync data from CouchDB to PouchDB for offline storage using the following code to retrieve data from CouchDB: db.replicate.from('http://test.iriscouch.com/todo','idb://todo', function (err, changes) { if (err) { conso ...

Utilize Javascript ES6 to Sort Through Data in a Table

I require assistance with my project using Material UI and React. There are two key implementations that I need: I am looking to create a filtering system for all rows in each column as shown in the attached image. Additionally, I need a button that can a ...

Error encountered: JSON parsing failed due to an unexpected token 'm' at the beginning of the data while

I am brand new to coding and am currently trying to follow the lecturer's instructions on webpacks. However, every time I attempt to use the command "npx webpack", I encounter this error message: "/home/ubuntu/workspace/assignment1/hellowp/webpack.con ...

Executing a setInterval function in NodeJs without prolonging the process's lifespan

To better grasp what I need to do, I simplified the task at hand: we have a lengthy nodejs process with numerous queued async functions, making it impossible to predict when they will finish. Our goal is to create an update process that stores the current ...

Filter list of items in a React application using checkboxes and an input field

Hey everyone, I'm trying to implement a filter function for an array exported from Node. I want to apply two conditions before filtering the objects in my array - one for checking the character's universe and another for their name. The filters w ...