Angular binding fails to trigger before a blocking function call

When a user triggers a specific action on my form by clicking a button, I want all controls to be disabled until the server response is received. This way, the user cannot modify any values while the action is being processed. Once the server responds, the form should be re-enabled.

However, the issue lies in my code implementation:

$scope.restartNode = function () {
            $scope.isBusy = true;
            $scope.disableControls = true;

            SEApplicationService.restartNode();

            $scope.isBusy = false;
            $scope.disableControls = false;
        }

The restartNode function makes a blocking call to a Web API method, but for some reason, the controls remain enabled. Interestingly, if I remove the line that re-enables the controls, they are properly greyed out as expected. What could be causing this behavior?

The blocking call is as follows:

appService.restartNode = function () {
        return $http.post("/SEFlex/SEFlexAdmin/RestartNode", {
            isPrimary: appService.primarySelected
        }).success(function (response, status, headers, config) {
            appService.refreshData();
        }).error(function (reason, status, headers, config) {
            console.log(reason);
        });
    }

Added an edit to include the refreshData() function:

appService.refreshData = function () {
        return $http.post("/SEFlex/SEFlexAdmin/GetNodesStatus")
            .success(function (response, status, headers, config) {
                if (response) {

                    angular.forEach(response.data, function(value) {
                        if (value.isPrimary) {
                            appService.ServiceStatus.PrimaryStatus = value.status;
                            appService.ServiceStatus.PrimaryPools = value.poolCount;
                            appService.ServiceStatus.PrimaryContainers = value.containerCount;
                            appService.ServiceStatus.PrimaryNodes = value.nodeCount;
                        } else {
                            appService.ServiceStatus.SecondaryStatus = value.status;
                            appService.ServiceStatus.SecondaryPools = value.poolCount;
                            appService.ServiceStatus.SecondaryContainers = value.containerCount;
                            appService.ServiceStatus.SecondaryNodes = value.nodeCount;
                        }
                    });
                }
            })
            .error(function (reason, status, headers, config) {
                console.log(reason);
            });
    }

Answer №1

The issue lies in the fact that the request is asynchronous, and you are not waiting for the response before changing your busy and disable variables.

To solve this, wrap them within the promise callback of the restart function.

 $scope.restartNode = function () {
        $scope.isBusy = true;
        $scope.disableControls = true;

        SEApplicationService.restartNode().then(function(){
            $scope.isBusy = false;
            $scope.disableControls = false;
        }).catch(function(err){
            // any rejected promises in the chain will be caught here
        });            
    }

UPDATE: In order to properly create a promise chain with restartNode and refreshData, replace success with then. This is why success is being deprecated:

appService.refreshData = function () {
    return $http.post("/SEFlex/SEFlexAdmin/GetNodesStatus")
        .then(function (response, status, headers, config) {
             var responseData = response.data;
            if (responseData ) {

                angular.forEach(responseData.data, function(value) {
                    // code omitted for brevity
                });
            }
        });
 }

Then, you can return the refreshData promise within the then function of

SEApplicationService.restartNode()

 appService.restartNode = function () {
    return $http.post("/SEFlex/SEFlexAdmin/RestartNode", {
        isPrimary: appService.primarySelected
    }).then(function (response, status, headers, config) {
        return appService.refreshData();
    })
}

Answer №2

To achieve this, you can implement a callback function in the following way:

$scope.refreshServer = function () {
            $scope.isBusy = true;
            $scope.disableControls = true;

            ServerService.refresh(function(){

                  $scope.isBusy = false;
                  $scope.disableControls = false;

             });

        }

Below is the server-side function code:

serverService.refresh = function (callback) {
        return $http.post("/ServerApp/RestartServer", {
            isPrimary: serverService.selected
        }).success(function (response, status, headers, config) {
            serverService.reloadData();
            callback();
        }).error(function (error, status, headers, config) {
            console.log(error);
            callback();
        });
    }

Answer №3

Make sure to add a scope.$apply() following the assignment of $scope.disableControls = false;

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 issues with integrating interactjs 1.7.2 into Angular 8 renderings

Currently facing challenges with importing interactive.js 1.7.2 in Angular 8. I attempted the following installation: npm install interactjs@next I tried various ways to import it, but none seemed to work: import * as interact from 'interactjs'; ...

Implementing an onclick function to initiate a MySQL update query

<?php include_once("db.php"); $result=mysql_query("SELECT * FROM stu WHERE receiver='DM4'"); while($row=mysql_fetch_array($result)){ echo "<tr>"; echo "<td>" . $row['ptype'] . "</td>"; echo "<td>" . $row[&apo ...

What is the best way to manage the loading and unloading of JavaScript within dynamically loaded partial pages?

Utilizing jQuery and history.js, I manage seamless transitions between partial pages to prevent entire document reloads. Some of these partial pages include unique javascript files. Despite successful page transitions, remnants of executed javascript linge ...

Error message from @firebase/database: The Firebase Database URL could not be identified. Please ensure that you provide a Project ID when initializing firebase.initializeApp(). This issue is specific

Currently, I am in the process of setting up a live chatroom. Initially, everything was working perfectly on my first attempt. However, when I had to focus on another task and returned to this project, I encountered an error message stating that I cannot i ...

Is there a way for me to acquire the Amazon Fire TV Series?

I'm currently working on developing a web app for Amazon Fire TV, and I require individual authorization for each app. My plan is to utilize the Amazon Fire TV serial number for this purpose. However, I am unsure how to retrieve this serial using Jav ...

Is it possible to add a click-listener after a change in state has occurred?

Here is a component I am working on: <div ref='carousel' onClick={this.mobileZoomOut()} className='carousel'> The mobileZoomout function is designed to handle a specific condition for smaller screens: mobileZoomOut () { c ...

Restricting the input range with JQuery

Need assistance with limiting user input in a text box for amounts exceeding a specified limit. Attempted using Ajax without success, considering jQuery as an alternative solution. Any expertise on this matter? function maxIssue(max, input, iid) { v ...

What is the best way to have DOMDocument processed in PHP after running Javascript?

Currently, I'm working on a program that searches for tags. Unfortunately, I'm encountering difficulties retrieving tags created with JavaScript. ...

Determine if I'm actively typing in the input field and alter the loader icon accordingly with AngularJS

Just delving into the world of AngularJS and attempting to tweak an icon as I type in an input box. Currently, I can detect when the box is focused using the following code: $scope.loading = false; $scope.focused = function() { console.log("got ...

Learn how to decrypt messages using CryptoJS AES with a successful Ruby demonstration

Decoding AES encrypted messages with Ruby is possible using the following code: require 'openssl' require 'base64' data = "IYkyGxYaNgHpnZWgwILMalVFmLWFgTCHCZL9263NOcfSo5lBjAzOZAtF5bF++R0Bi+9c9E+p3VEr/xvj4oABtRWVJ2wlWzLbYC2rKFk5iapFhb7 ...

Amchart 5: Tracking Cursor Movement on the X Axis

I am a beginner with amCharts5 and I am in need of assistance to retrieve the actual X value of the cursor on my chart (where the X axis represents dates). I have come across helpful examples for amCharts 4, but nothing seems to work for amCharts 5. Is thi ...

Learn how to pass an id from the query parameters to the getInitialProps function in Next.js

Looking to create a basic website that displays content from a database? Utilizing the getInitialProps function from Next.js documentation can help with server-side rendering: https://nextjs.org/docs/api-reference/data-fetching/getInitialProps#getinitialpr ...

Manipulate a JavaScript array for optimal utilization in Google Charts by flattening the days nested within the array

Here is an array [ ["04/21/2021", 405, 85, 30] ["04/18/2021", 350, 135, 30] ["04/16/2021", 335, 120, 30] ["04/15/2021", 420, 100, 30] ["04/15/2021", 405, 85, 30] ["04/15/2021", 350, 13 ...

Serving pages with Node JS and loading .js files on the client side

Here is a simple JS file that will be familiar to those who have worked with Socket.IO in NodeJS and Express: var express = require('express'), app = express(), server = require('http').createServer(app), io = require(&apos ...

Adding the necessary attribute dynamically to a select element

I'm currently working on creating an adapter to allow the client-side validation markup generated by ASP.Net MVC to function with AngularJS. I've come across an interesting issue while trying to dynamically add the required attribute using a dire ...

What steps can be taken after the addClass function has been triggered?

I am trying to achieve a functionality where upon clicking a button, a div will add a class that changes its width to 150px. However, I want something to be shown in console.log only after the div has become 150px in width. Can anyone assist me in achievin ...

Retrieve a pair of values in a Node.js JavaScript application

I'm in search of a solution to locate an item and its index within an array, and then store them in separate variables. Though I'm relatively new to programming, I'm encountering challenges in tackling this problem. I attempted to use destru ...

What is the best way to obtain the clicked ID when a user clicks on an element within

As a budding web developer, I've been working on a code snippet to dynamically load data into an iframe: $(document).ready(function () { function loadMaterials(type, query) { $.ajax({ type: 'GET', url: &ap ...

`How can one transfer data values from Views to Templates in Django?`

At the moment, I currently have two template files named no_results_tickets.html and results_tickets.html. The first template consists of two drop-down menus that allow users to select a year and a week number. Upon hitting the submit button, the web appli ...

Basic exam but located in a place that is not valid

Here is a test I am working on: // import {by, element, browser} from "protractor"; describe('intro', () => { beforeEach(() => { browser.get(''); }); it('should have multiple pages', () => { let buttonOn ...