Optimal method for setting up a controller with multiple asynchronous requests

I am utilizing 2 $http functions within my AngularJS application to populate the page content. These functions are called using ng-init.

ng-init = "getOpen(); getClosed();"

Is this the most optimal approach?

The first function is as follows:

$scope.getOpen = function () {
    $http({
        method: 'post',
        url: "http://www.example.co.uk/php/open-get.php",
        data: $.param({ 'location' : $scope.l, 
                       'time' : $scope.t,
                       'day' : $scope.d,
                       'type' : 'get_restopen' }),
        headers: {'Content-Type': 'application/x-www-form-urlencoded'}
    }).
    success (function(data, status, headers, config){
        if(data.success && !angular.isUndefined(data.data) ){
            $scope.open = data.data;
        } else {
            $scope.open = [];
        }
    }).
    error(function(data, status, headers, config) {
        //$scope.messageFailure(data.message);
    });
}

The second function is as follows:

$scope.getClosed = function () {
    $http({
        method: 'post',
        url: "http://www.example.co.uk/php/closed-get.php",
        data: $.param({ 'location' : $scope.l, 
                       'time' : $scope.t,
                       'day' : $scope.d,
                       'type' : 'get_restopen' }),
        headers: {'Content-Type': 'application/x-www-form-urlencoded'}
    }).
    success (function(data, status, headers, config){
        if(data.success && !angular.isUndefined(data.data) ){
            $scope.closed = data.data;
        } else {
            $scope.closed = [];
        }
    }).
    error(function(data, status, headers, config) {
        //$scope.messageFailure(data.message);
    });
}

My AngularJS implementation seems to be functioning well. However, I would like some insights on the efficiency of my current method.

1 - Are my $http requests executed concurrently or does one complete before the other one starts?

2 - Would it be beneficial to incorporate $q or promises in my code? Considering that these functions operate independently.

3 - How can I determine when all $http requests have finished execution, regardless of their outcome?

Am I correct in assuming the following code snippet accomplishes this?

$q.all([$scope.getOpen, $scope.getClosed]).then(function() {
     //Both requests have been completed and I shall now set a boolean
     $scope.complete = true;
});

Answer №1

  1. If you are the one invoking both functions, then yes, $http calls are inherently asynchronous.

  2. No need to worry because $http actually returns a promise already!

  3. For a seamless approach without altering the promise return, consider using Promise.all() as a completion monitor. More insights can be found on the promise reference page

Answer №2

When setting up my page, I have two $http functions that I call using ng-init to populate the data on the page.

The ng-init code looks like this: "ng-init = "getOpen(); getClosed();""

I'm wondering if this is the most effective method?

According to the angular documentation:

Using ngInit in your templates can lead to unnecessary complexity. The directive should only be used for specific purposes such as aliasing properties in ngRepeat or injecting data from server-side scripts. In most cases, it's recommended to use controllers instead of ngInit for initializing scope values.

You can read more about it here: https://docs.angularjs.org/api/ng/directive/ngInit

Avoid using ng-init directly in your templates. Instead, it's better practice to initialize data within a controller by calling a private function.

I also suggest referring to the Angular style guide found at:
https://github.com/johnpapa/angular-styleguide

1 - Do my $http calls run simultaneously or does one finish before the other starts?

Both calls are initiated almost simultaneously. JavaScript maintains a stack of callbacks to execute once responses are received from the server. You can check the network tab in your browser console to see all requests being made.

Moreover, note that `.success` is now deprecated and you should use `.then` instead. Refer to: https://docs.angularjs.org/api/ng/service/$http#deprecation-notice

2 - Is it necessary to introduce $q or promises in my code? The functions are independent.

In this scenario, there's no need for $q or promises. However, you could utilize `$q.all([promise1, promise2])` if you want to execute something after both calls have completed.

3 - How can I determine when all $http requests have finished, regardless of success?

You can explore $httpInterceptors for handling this situation. Here's some sample code implementation:

angular.module("myModule").factory("myHttpInterceptor", [
    "LoadingService",
    "$q",
    "Alert",
    function (LoadingService, $q, Alert) {

        function requestInterceptor(config) {
            LoadingService.increaseCounter();
            return config;
        }

        function responseInterceptor(response) {
            LoadingService.decreaseCounter();
            return response;
        }
   // ...

Is the following code correct?

$q.all([$scope.getOpen, $scope.getClosed]).then(function() {
     // Both requests have been completed, now set a boolean
     $scope.complete = true;
});

No, because you still need the promise returned by your function. Additionally, `.success` does not support promise chaining, so you should use `.then()` instead.

$scope.getOpen = function () {
    return $http({
        // configuration
    }).
    then(function(data, status, headers, config){
        // handle success
    },(function(data, status, headers, config) {
        // handle error
    });

Summary:

angular.module("yourApp").controller("someController", ["$scope", "$q"
    function($scope, $q){

        // initialization
        init();

        // Shared functions

        $scope.getOpen = function () {
          return $http({
             method: 'post',
             url: "http://www.example.co.uk/php/open-get.php",
             data: $.param({ 'location' : $scope.l, 
                   'time' : $scope.t,
                   'day' : $scope.d,
                   'type' : 'get_restopen' }),
             headers: {'Content-Type': 'application/x-www-form-urlencoded'}
          });

        $scope.getClosed = function () {
          return $http({
            // configuration
          });

        // private functions
        function init(){
             var promises = [];

             promises.push($scope.getOpen());
             promises.push($scope.getClosed());

             $q.all(promises).then(function(datas){
                  // At this point, both calls have succeeded
                  // datas[0] contains result of $scope.open()
                  $scope.open = datas[0].data;
                  $scope.complete = true;

             }, function(errors){
                  $scope.complete = true;
                  // This block executes if any call fails
             });
        }

    }
]);

Answer №3

Since $http in asynchronous, it allows your 2 calls to be executed simultaneously. If you find the need to condense both functions into one, or if you want to ensure all $http requests are finished, consider using $q.all. Learn more about Angularjs $q.all here

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

Ways to identify when a person has scrolled a specific distance

Is it possible to modify the appearance of my top navigation bar once the page has been scrolled a specific number of pixels? I assume this requires some sort of listener to track the amount of scrolling. I came across element.scrollTop, but it doesn' ...

Attributes requested with jQuery JavaScript Library

Is there a way to dynamically add extra key-value pairs to the query string for all requests sent to the web server? Whether it's through direct href links, Ajax get post calls or any other method, is there a generic client-side handler that can handl ...

Please provide me with the steps to relocate the src/pages/api folder to src/ in a Next.js project

When working with Next.js, I am interested in relocating the src/pages/api directory to be located under src/, much like how it is done in blitz.js. In this case, the directory structure would look something like this: src |- pages |- api Unfortunately, I ...

Angular8: Stay Updated with Real-Time Data Refreshment

I've implemented code in my app.component to retrieve all users. I'm facing an issue where if I have two windows open and perform any CRUD actions, the second window displays outdated data. To address this, I am attempting to refresh the page ev ...

What is the reason behind localStorage.getItem consistently returning a string value?

Something strange is happening. In the lib.dom.d.ts file, the type for localstorage.getItem shows as 'string | null', but in my app it always returns a string. Why is this discrepancy occurring? ...

Limiting scope on a parent component hinders the ability to communicate with its child

I'm working with the following HTML structure: <div class="row" loader="loader" address-book> <!-- Loading complete - this should show result --> <div loader-success></div> <!-- Loading failed - this should sho ...

determining if a condition is vacant or occupied

Seeking assistance in determining if the array is empty or not. What are the conditions for this? An empty array appears as follows: [ { "readTime": "2019-09-09T15:20:44.648599Z" } ] A non-empty array looks like this: [ { "d ...

Steps for deploying an ejs website with winscp

I have developed a Node.js web application using ExpressJS, with the main file being app.js. Now I need to publish this website on a domain using WinSCP. However, WinSCP requires an index.html file as the starting point for publishing the site. Is there ...

Arranging squares in a circular formation with Three.js

I am facing an issue with aligning squares within a circular grid to its center. Despite the correct center point, the entire grid is consistently skewed to the right. The problem could be due to incorrect calculations for removing squares outside the cir ...

Utilize AJAX to connect to a remote domain from an extension

I am currently working on creating a Chrome extension that will utilize AJAX to fetch data from a specific webpage and then generate notifications based on the content of that page. The webpage I am targeting is a ticketing system, and my goal is to deter ...

Ways to set values for an array of objects containing identical key names

let people = [ { firstName: 'Ben' }, {firstName : 'Bob' } ]; let location = { city: 'Dublin' , Country: 'Ireland' } ; let result = []; let tempObj = {}; for(let person of people){ tempObj = Object.assign({}, ...

Tips for updating border color when focused with styled-components

How can I change the border color of an input on focus using styled-components and React? Here is the code snippet I am currently using: import React from "react"; import PropTypes from "prop-types"; import styled from "styled-components"; const String ...

Nested modal in native app utilizes the React Carbon TextInput component for an uneditable input field

As a newcomer to React, I have encountered an issue with the Tauri framework used to bundle my React application as a desktop app. Specifically, I am facing a problem where the TextInput field, nested inside a modal and utilizing React Carbon components, i ...

Error: Uncaught ReferenceError - 'channel' has not been defined

I'm currently working on a Discord bot that is designed to handle tickets and I'm facing an issue with sending messages in the newly created channel I attempted using .then, but for some reason it's not functioning as expected and I'm ...

Issue with navigation links on HTML website not functioning as expected

I would like the dropdown menu items to be clickable. For example: Menu item: Services Sub items: - branding } These already have working links - marketing } However, when I try to replace '#' with a link for Services, it d ...

Displaying content using asynchronous JavaScript and XML (AJAX

I'm currently working on implementing an infinite scroll feature, where more content is loaded as the user reaches the bottom of the page. I am making an ajax call and attempting to render a new view on the backend before sending it back to the fronte ...

Every time I try to set up the MailChimp pop-up javascript, I encounter an Uncaught Error message saying that Bootstrap tooltips need Tether and an Uncaught ReferenceError message

Utilizing Wordpress and Understrap. Upon inserting the following code: <script type="text/javascript" src="//downloads.mailchimp.com/js/signup- forms/popup/embed.js" data-dojo-config="usePlainJson: true, isDebug: false"> </script><script ty ...

Updating user attributes as an administrator using the Cognito SDK

Currently, I am in the process of developing an Angular application and I aim to integrate authentication using AWS Cognito (my experience with AWS is fairly limited). So far, I have successfully incorporated features such as sign-up, sign-in, sign-out, MF ...

A unique string containing the object element "this.variable" found in a separate file

Snippet of HTML code: <input class="jscolor" id="color-picker"> <div id="rect" class="rect"></div> <script src="jscolor.js"></script> <script src="skrypt.js"></script> Javascript snippet: function up ...

The server is sending unprocessed raw JSON data that Angular is unable to handle

I've been working on accessing data from the server and storing it in $scope.resp, but I'm only seeing raw JSON displayed on the page. Here is the code from routes/addr.js: router.get('/', function(req, res) { var persons = [{add ...