Mastering the art of linking together recursive Ajax load promises in TypeScript

I'm making an effort to adhere to good jQuery practices and utilize promises, but I still struggle with some basic concepts.

Below is a panel loading method that might need to redirect to another page instead of loading the originally specified one. This redirection is determined by the server (e.g., based on the user's previous response).

private _loadNewPanel(url: string, data?: any): JQueryPromise<any>
{
    var THIS = this;
    var dfd = $.Deferred();
    var promise = dfd.promise();

    $.ajax({
        cache: false,
        url: url,
        type: data ? "POST" : "GET",
        data: data
    })
        .done((html: string, textStatus: string, jqXHR: JQueryXHR) =>
        {
            var location = jqXHR.getResponseHeader('redirect-url');
            // Server indicates a need to redirect
            if (location)
            {
                // Continue with the new load request
       // **** WHAT SHOULD BE DONE HERE WITH THE RETURNED PROMISE ***
                THIS._loadNewPanel(location, null);
            }
            else
            {
                dfd.resolve(html);
            }
        }).fail((jqXHR, textStatus: string, errorThrown: string) =>
        {
            dfd.reject(errorThrown + ": " + url);
        });

    return promise;
}

Could simply adding .done() to the recursive call like this and returning the results be a solution?

       // Continue with the new load request
       THIS._loadNewPanel(location, null).done(function(html){
             dfd.resolve(html);
       }).fail(function(error: string){
             dfd.reject(error);
       });

Is there a more concise way to write this code? Am I overcomplicating things with jQuery promises?

Answer №1

A more efficient way to write the entire process exists. The $.ajax function already utilizes promises.

To utilize the promise it generates, simply return it:

 THIS._loadNewPanel(location, null).done(function(html){
         dfd.resolve(html);
 }).fail(function(error: string){
         dfd.reject(error);
 });

This can be simplified to:

 return THIS._loadNewPanel(location, null); // why is THIS uppercase here :P? 

Similarly in the code above. Deferreds are only necessary at the lowest level of your API and if the API does not inherently handle errors. In fact, what you have done is referred to as the deferred anti pattern.

If you wish to chain the response, you can use .then:

var req = $.ajax({...}).then(function(resp){
      var location = req.getResponseHeader("redirect-url");
      if(location) return THIS._loadNewPanel(location, null); // NOTE THE RETURN
      return resp;
});
return req;

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

Viewing CSV Headers with PapaParse Plugin

I am currently utilizing the PapaParse plugin to handle CSV files. I have implemented a function that generates a table for displaying the results extracted from the CSV file. function processFile(evt) { var document = evt.target.files[0]; Papa.parse(doc ...

Error with Jquery authentication

Take a look at the code snippet below: var jsonData1 = $.ajax({ url: 'http://'+domainName+':9898/jolokia/read/*', dataType:"json", crossDomain: true, beforeSend: function(xhr){ var username= '*&a ...

The Best Way to Refresh a ReactJS Component in Plain HTML/JavaScript

So here's the situation. I'm diving into creating a React Modal component that can seamlessly integrate with any vanilla HTML / JS file. By generating a bundle.js file using Webpack from my React component, it becomes easier to inject it into a d ...

Interactive Infographics in HTML5 format

Currently, I am unable to find any examples on how to accomplish a specific task mentioned in the following link. If you have a tutorial with step-by-step instructions or a code project available, it would greatly assist me. Link: Evolution of WEB ...

Choose a particular component from a snippet of a view

I am facing challenges with implementing a JavaScript function in a partial view. My objective is to validate the email input and display a message based on the validation result. The email field is located inside a partial view that is dynamically loade ...

Trigger a function upon window reload with the click of a single button

$('#start').click(function () { window.location.href=window.location.href; runme(); }); I have a simple goal: whenever the user clicks the start button, I want the page to reload while still executing the custom rume function. Is there a w ...

Convert a div into a clickable link using JavaScript without using too many classes or any ids

After using shortcodes generated by functions.php in a WordPress parent theme, I have come across the following HTML code: <div class="pricing-table-one left full-width "> <div class="pricing-table-one-border left"> <div class=" ...

Deleting an HTML column that has a dynamic header name <th> can be achieved by following these steps

I have a script that can add a new column to an HTML table. When the user clicks on add group, the header will change to Group1, Group2, and so on. I am currently adding a function for delete group that can delete all the added columns. The issue now is th ...

Prevent the automatic inflation of bubbles on the D3 World Map

Currently, I am developing a D3 world map with a zoom feature that allows users to zoom in up to the boundary level of any country or county by clicking on it. I have successfully added bubbles that point to various counties in Kenya, and these bubbles en ...

Using Bootstrap4 tagsinput, removing a tag: detecting for AJAX fulfillment and then reversing the action

Utilizing tagsinput in conjunction with bootstrap4, my goal is for the user to be able to delete a tag by clicking on the 'x' button. Upon deletion, an ajax request is sent to the server to verify if the user has permission. The server will respo ...

Exploring the Behavior of Subscribing to a Shared Service in Angular

Within my Angular project, I have implemented a service to share variables across different components. The code for this service is as follows: import { Injectable } from "@angular/core"; import { BehaviorSubject } from "rxjs"; @Injectable() @Injectable( ...

Encountering a 500 error while making a Jquery and ASP.NET ajax call to a .NET server

After creating an object in the following format : Object {ABC-123: "XYZ", ABC-112: "LAX"} I encountered a 500 error while attempting to send this object to .NET. Here's how I tried to transmit the object: $.ajax({ type: "POST", ...

What is the reason that utilizing $("input").first() does not function properly on Google Forms?

While practicing with Selenium, I encountered an issue while using this Google form. Specifically, I found that I couldn't select the first input field by using $("input").first() To confirm this issue, I turned to the web browser (Firefox) console t ...

Securing important code sections in Node/Express using Typescript: A guide

I'm fairly new to the world of JavaScript/Typescript/Node/Express, and as I've been researching, it seems there isn't a universally accepted method for locking critical sections of code in a Node/Express application. I've come across a ...

Path for WebStorm file watcher's output

I'm in the process of setting up a Typescript project in WebStorm, where I want the files to be transpiled into a dist folder. This is my current project folder structure: projectroot/src/subfolder/subfolder/index.ts What I aim for is to have the f ...

What steps can I take to ensure that the submenu remains visible for users to make their selection?

I'm currently working on implementing a drop-down sub-menu next to the navigation bar located in the center of the image. I have uploaded an image of a transparent box (representing the background of the sub-menu) and used the following codes: When h ...

Displaying JQuery dialogs briefly show their contents before the page finishes loading

Utilizing jquery 1.10.3, I am creating a dialog that is quite intricate. When I say 'intricate', I mean that the dialog's content includes data from a database, such as dropdown lists populated by the results of database queries, alongside s ...

Encountered an issue while attempting to retrieve data from the HTTP URL

I encountered an issue when trying to make a request to an HTTP URL from another domain using AJAX. Every time I attempt this, I receive an error callback. DOMException: Failed to execute 'send' on 'XMLHttpRequest': Failed to load { ...

Guide to sending files via AJAX in CodeIgniter

I am facing an issue with uploading a file using ajax along with other parameters. The files are not getting uploaded successfully. Form Code <form id="first_form" method="post" enctype="multipart/form-data"> <input type="file" id="file" nam ...

Using p5.js with TypeScript and Webpack is not supported

I'm currently working on a library project that involves utilizing p5.js. Specifications Here is a snippet of my Webpack configuration: const path = require('path'); module.exports = { entry: './start.ts', output: { ...