Calling http.get one after the other without knowing the length of the list

Suppose I have a list of URLs as follows:

var myurls = ['http://server1.com', 'http://server2.com', 'http:sever2.com', etc ]

Each URL is considered a "fallback" and should only be used if the previous one is unreachable. This list establishes a priority order. Let's also assume that this list can vary in length - its size is unknown and needs to be iterated through.

How can I write a function, named "reachability", that loops through this array and returns the first server that can be reached?

I cannot use $http.all since it executes requests in parallel. Additionally, running a while loop with an $http.get within it is not feasible because the response may be delayed, causing the user interface to freeze in the meantime.

It's worth mentioning that jQuery is not being utilized; instead, Ionic framework, which includes a version of jQuery-lite, is being used.

While many examples propose chaining promises using .then, this approach assumes prior knowledge of the number of URLs, which is not the case here.

Thank you.

Answer №1

To simplify the process, iterate over the array:

myurls.reduce((previous, currentUrl) => previous.catch(() => http.get(currentUrl).then(() => currentUrl)),
              Promise.reject());

Explanation of the Flow:

This method is based on a common pattern where reduce is used to create a promise chain. For example:

[func1, func2].reduce((p, f) => p.then(f), Promise.resolve());
which is equivalent to
Promise.resolve().then(func1).then(func2)
(the last argument in reduce acts as the initial value).

In your scenario, since you are attempting retry on failure, it is necessary to construct a retry (or reject) chain by starting with Promise.reject() instead. Hence,

Promise.reject().catch(func1).catch(func2)

Answer №2

If you're looking for a solution that involves recursion and chaining, consider the following approach:

const findFirstReachableUrl = (urls) => {
  if (urls.length > 0) {
    return $http.get(urls[0]).then(() => {
      return urls[0];
    }).catch(() => {
      return findFirstReachableUrl(urls.slice(1));
    });
  } else {
    return $q.reject("No reachable URL");
  }
}

To use this function, make the following call:

findFirstReachableUrl(myurls).then((firstReachableUrl) => {
  // Success: perform actions with firstReachableUrl
}, () => {
  // Failure: unable to reach any URLs
});

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

Toggle the visibility of table rows using checkboxes

I'm working with checkboxes to toggle the visibility of specific rows in a table based on their content matching the selected checkbox values. Checkboxes: <input type='checkbox' name='foo1' value='foo1' v-model="sele ...

Do JavaScript Promises operate asynchronously?

Can we clarify if JavaScript Promise is asynchronous? I've been researching Promise and async programming, particularly with ajax requests. If Promise isn't inherently async, how can we make it so? For instance, consider a function that encapsul ...

Tips for positioning the labels in a sankey diagram for optimal alignment

When multiple values are the same in this scenario, such as 0, the labels start to overlap. Can anyone provide guidance on how to align these labels vertically? Ideally, I would like them to be positioned at the top of the node/bar. Highcharts.chart(&apos ...

Why are NodeJS and Jade/Pug variables not being recognized in the Jade script?

After successfully passing a variable to Jade like #{myvar}, I encountered an issue when trying to access it in a script block. Despite using typeof(myvar) and confirming that it was initially undefined, my attempts to display its value within the script b ...

Initiate a timer with intervals of 3 seconds upon reaching a designated section in a React application

useEffect(() => { console.log(window.scrollTo) console.log(textInput.current.offsetTop); }, [textInput,]) click here for more information check out the bottom of this page for a similar countdown feature - any ideas on how to implement it? ...

AngularJS: Getting language details in AngularJS based on language code

When working with Android, it is possible to obtain language information directly from the language code using the Locale class. The example below demonstrates this: Locale locale = new Locale("fr"); locale.getDisplayName(locale); // Français locale.getD ...

AngularJS continuously updates and adds results to a list using long polling techniques

At present, I am able to push long polling results to the $scope.newMsg variable. However, my goal is to append it to the messages list using $scope.messages.push(msg). This is the current app.js code snippet: var messageApp = angular.module('messag ...

Oops! There seems to be an error in the code: SyntaxError: DOM Exception 12 setRequestHeader@[

Currently working on the development of a mobile application for Android and IOS using Phonegap, AngularJS, and CORS_REST. Most headers are functioning well on Android, but encountering issues when testing on iPhone with GapDebug. An example of the authen ...

Setting environmental variables throughout your application using create-react-app on the front end

Hey there! I have a simple Todo app with the client using create-react-app and the server running on node. I'm struggling to properly set environment variables across my app. I've placed my .env file in the root directory of the app, which curre ...

Issues with sending parameters in JQuery Ajax POST request

Currently, I am delving into Ajax and encountering some issues with sending requests from the client side. I have a jsp file located at "/web" on my local server to manage requests. Though unsure if this is the best approach or if it should be handled by ...

Tips for verifying the input field with specific requirements in Angular 6

There is an input field that needs to validate text based on certain logic conditions: No spaces should be allowed in the formula. The operators (and,or) must be lowercase and enclosed in curly brackets {}. The number of opening '(&apos ...

"Enhancing User Experience with Animated Progress Bars in Three.js

Is there a way to create a progress bar animation in three.js? I've been grappling with this issue for quite some time now. I attempted to replicate the html5 video player progress bar method, but unfortunately, it doesn't seem to be compatible w ...

Ways to access the files attribute in an input tag in AngularJS without relying on getElementById

I am currently working on file uploads using AngularJS and I have a question regarding how to retrieve input files similar to regular JS. What I want to achieve: HTML: <input type="file" name="file" id="fileImg" accept="image/*"> JS: var file ...

Placing a dropdown menu on top of an image

I currently have a slightly rotated menu bar with two buttons as an example: https://i.stack.imgur.com/0sI2P.jpg Due to the rotation, normal HTML handling is not feasible. I am considering using a <map> element to create hyperlinks over the menu it ...

Node.js encountering issue with printing an array

Here is the code snippet from my routes file: router.get('/chkjson', function(req, res, next) { req.getConnection(function(err,connection){ var ItemArray = []; var myset = []; var query = connection.query('SELEC ...

What is the best way to adjust the placement of a component to remain in sync with the v-model it is connected to?

I am encountering an issue with 2 sliders in my project. I have set it up so that when the lower slider's value is greater than 0, the top slider should automatically be set to 5. I am using a watcher function for this purpose. However, if I manually ...

Implementing pagination within nested ng-repeat in Angular app

I am currently utilizing Angular along with the Material library in my project. I am facing an issue with two nested ng-repeat loops within md-tables. The problem lies in the fact that the variable is getting overridden with each request in the nested loop ...

The jquery error NS_ERROR_XPC_BAD_CONVERT_JS is causing issues on Google Chrome while working fine on Firefox

Currently, I am utilizing jQuery to dynamically add fields to a form. These are considered "repeatable" fields since users can click an "add more" button. Here is the code snippet: $(".add-attacker-scores").click(function() { count = count + 1; ...

Getting JSON values from Angular and storing them in MongoDB is a straightforward process. Here

How can I save data assembled from different partials into a single JSON object in MongoDB using my controller? Here is a sample of the code I am working with: $scope.dataIS = [ {comm:'comm1', property_name:'property_name1', prope ...

Creating a jQuery alert similar to Stack Overflow's and integrating it with server-side functionality

I recently asked a question but unfortunately couldn't find the answer I was looking for. I came across this discussion on Stack Overflow about creating an alert box with dynamic data, but it wasn't exactly what I needed. After searching online ...