The Angular scope remains static during service calculations and does not reflect immediate updates

Is there a way to display a message on the scope indicating that a function in a service is currently being calculated and taking a long time? I have set up a simplified example in this jsfiddle: http://jsfiddle.net/rikboeykens/brwfw3g9/

var app = angular.module('myApp', []);

app.service('testService', function(){
    this.longFunction=function(){
        for (var i=0; i<1000000000;i++){


        }
    }
});

function TestCtrl($scope, testService)
{
    $scope.$apply(function(){$scope.waiting="not waiting";});
    $scope.longFunction = function(){
        $scope.waiting="waiting";
        testService.longFunction();
        $scope.waiting="not waiting";
    }
}

The longFunction on the testService takes about two seconds to complete, but $scope.waiting is not updated to "waiting" while this is taking place.

I tried using $scope.$apply but then I just get an error saying $apply is already in progress.

Would it work if I perform the longFunction on the testService asynchronously? I have been looking into using promises but I'm not sure how I would go about implementing them.

Answer №1

Utilize the $timeout feature for better performance.

function ExampleCtrl($scope, exampleService, $timeout)
{
   $scope.status="not in progress";
    $scope.timeConsumingTask = function(){
        $scope.status="in progress";
        $timeout(function(){
          exampleService.performTask();
          $scope.status="not in progress";
        })
    }
}

Answer №2

The functionality is operational, however the waiting message may not be visible due to the synchronous execution of the longFunction, which hinders the UI from updating and displaying the waiting message. Once the longFunction call concludes, the UI becomes idle and displays the "not waiting" message rather than the expected "waiting" text.

This behavior is common in Web browsers as all operations take place within the UI thread, resulting in a freeze if activities are synchronous and causing a delay in refreshing the screen until the long operation completes. To overcome this, utilizing the setTimeout method within Angular can mimic an asynchronous process, allowing the UI to take precedence and reflecting the message change accordingly:

$scope.longFunction = function(){
        $scope.waiting="waiting"; 

        // This serves as a workaround, addressing the absence of a seamless way to queue asynchronous tasks within the JS UI layer. By the way, Web Workers could also be worth exploring in this context! ;)
        $timeout(function() {
            testService.longFunction();
        }, 0);

        $scope.waiting="not waiting";
}

Answer №3

Utilizing the $timeout function is essential for executing a service function. An illustrative example can be found on Codeopen.io: http://codepen.io/skymk/pen/EjNpKL?editors=101

app.controller('Controller', ['$scope', 'testService', '$timeout',  function($scope, testService, $timeout) {
    $scope.waiting="not waiting";
    $scope.longFunction = function() {
        $scope.waiting="waiting";
        $timeout(function() {
          testService.longFunction();
          $scope.waiting="not waiting";
        }, 0);    
    }
    $scope.longFunction()
}])

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

Using only native JavaScript Vanilla, Rails does not execute create.js via Ajax

Concerning Rails 4 and Vanilla JavaScript, I encountered an issue with my code for creating a Shop record via Ajax. The record is successfully created, but the create.js file is not being triggered as expected. A strange occurrence happens in Chrome where ...

Sending an error code that is specific to the situation to the AJAX error function

I am attempting to send a custom error code to the client-side for ajax error handling. On the server side: $response = array(); if ( empty($post['parent_id']) ) { $response = array('error' => true, 'status_code' => ...

The onLayoutChange function keeps overwriting the data stored in my local storage

When my layout changes, the new changes are saved into local storage and the layout state is updated. onLayoutChange(layouts) { saveToLS("layouts", layouts); } However, an issue arises when the page is refreshed. The layout g ...

Astro3.0 unable to locate images

I'm working on a simple astro project that is structured like this: └── src    ├── assets    │   └── images    │      └── blend.webp    ├── components    │   └── CoffeeCard.astro    ...

The glow shader for front face is not displaying correctly in Chrome, but it functions fine in other web browsers

I have encountered an issue where I am attempting to apply a custom shader material to a series of nested objects in order to create a glow effect around each node. The effect works perfectly on my personal laptop (running Windows 8.1 and the latest versio ...

Issue with nested state controller not being triggered

I am facing an issue with nested states in my Angular application. The parent state is executing fine, but the child state is not being triggered. The URL structure I am working with is: #/restaurant/2/our-food What I want is for the application to first ...

AngularJS: Issues with UI Router going unnoticed

My angular ui route structure is very straightforward: In index.html: <div class="container"> <div class="header" ui-view="header"></div> <div ui-view></div> </div> In app.config: $stateProvider .state( ...

How can you deactivate the vue-router for specific routes? Is it possible to operate a single-page application backend while utilizing a non-single-page

I'm currently working on a website/webapp using Laravel 5.3 and Vue 2. Since SEO is crucial, I've decided to keep the frontend/crawlable part of the site in Laravel + Blade, with only minimal sections in Vue 2.0. This way, I can avoid using Ajax ...

Exploring and accessing elements and nested objects within a dynamically named element in JavaScript using JSON syntax

Receiving a JSON response from an API, here's what the data looks like: [{ "order_id":"1111", "restaurant_id":"ABC", "fullfillment":"Delivery", "order_channel":" ...

Convince me otherwise: Utilizing a Sinatra API paired with a comprehensive JS/HTML frontend

As I embark on the journey of designing a social website that needs to support a large number of users, I have come up with an interesting approach: Implementing Sinatra on the backend with a comprehensive REST API to handle all operations on the website ...

The output is not shown because the form data is not being generated properly by document.getElement

<html> <head> </head> <body style = "text-align:center;" id = "body"> <form id = "number" method="get" name="number"> <input type="text" id="number1" name="number1" value="" /> <input type="text" id="number2" name="nu ...

Press the return key to submit input in the text area without adding a new line

Looking for a solution to submit text entered in a Shiny textarea without using CTRL or CMD? Check out this binding. Pressing return should do the trick, but without adding a newline. A textarea is needed for ample input space without hiding any text. UPD ...

What is the best way to add an array inside an object?

Currently, I am in the process of developing an application using a combination of SailsJS, AngularJS, and MongoDB. One of the challenges I am facing is figuring out how to properly insert a data array into an object within my schema. The Example Schema ( ...

Flashing event triggers a modification in input value

I have a flash object that updates the value of a textarea element. I am looking for a jQuery event that will be triggered when the value of the textarea is changed by the flash object. My goal is to have a specific checkbox automatically change to a &apo ...

Sending data to server with Backbone (using save() function and php script)

Wondering if you can assist me with an issue I'm facing. I am trying to utilize Backbone's save() method and send data to a php file. However, I encountered a problem right at the beginning. When I execute the following in the browser's co ...

Ways to address a buffered data problem in Websocket Rxjs. When trying to send a message, it is not being received by the server and instead is being stored in a

Currently, I am utilizing Websocket Rxjs within my application. The connection is successfully established with the server, and upon subscribing to it, all data is received in an array format. However, when attempting to send data back to the server, it se ...

View an image in advance of uploading it and concealing any broken images

The foundational code for previewing an image before it is uploaded can be found at this link. Here are the codes: <script type="text/javascript"> function readURL(input) { if (input.files && input.files[0]) { var ...

What's the best way to show floating point numbers in a concise format while also maintaining the ability to perform calculations within this Vue app?

I'm currently developing a compact calculator application using Vue 3 and implementing some custom CSS. For the most part, everything seems to be functioning correctly, except for when the results are long numbers that extend beyond the display limit ...

Adding elements to list items

Here is some HTML code that I am working with: <div> <ul id="one"></ul> </div> I also have this code snippet for appending a li element to the ul: $("#one").append("<li id='libtn2630275Chat'><img id=' ...

Can you show me how to divide a number by a comma after every two digits and then save the result into two separate

Given a variable var Number = 2425;, the task is to split it into two parts and store them in separate variables. var data = 24; var month = 25; What would be the most efficient way to achieve this using JavaScript? ...