Building a conditional promise in AngularJS

My scenario involves retrieving an items array from localStorage.

var items = JSON.parse($window.localStorage.selectedResources)['server'];

var arr = [];

var idsArray = [];

angular.forEach(items, function (item) {
    idsArray.push(item.id);
});

After collecting the item IDs, I initiate an API call...

//Make the API call
ds.getBillInfo(idsArray)
.then(function(response){
    var serversList = [];
    for (var key in response) {
        // iterate over response

The issue arises when the items array is empty, causing idsArray to also be empty. This results in an error stating

Cannot read property 'then' of undefined
.

I aim to execute the lines inside the then block even if idsArray is empty as if there is no promise involved.

EDIT

When using

$q.all([ds.getBillInfo(idsArray)])
, the error disappears.

The definition of getBillInfo() function is as follows:

this.getBillInfo = function(idsArray){
    if(!idsArray.length) return;
    var segmentUrl = '';
    for(var i =0;i<idsArray.length;i++){
        if(i != (idsArray.length-1))
            segmentUrl += 'ids='+idsArray[i]+'&';
        else
            segmentUrl += 'ids='+idsArray[i];
    }
    return HttpWrapper.send('/api/bill?bill=t&'+segmentUrl, {"operation": 'GET'});
};

Answer №1

When working with the getBillInfo function, it is recommended to encapsulate your logic within a new Promise object and resolve it in case of an empty array.

For example:

self.getBillInfo = function(array){

  var deferred = $q.defer();

  if(array.length == 0){
     deferred.resolve([]); // return an empty list
  }
  else{
    var segmentUrl = '';
    for(var i =0;i<idsArray.length;i++){
         if(i != (idsArray.length-1))
            segmentUrl += 'ids='+idsArray[i]+'&';
         else
            segmentUrl += 'ids='+idsArray[i];
        }
       HttpWrapper.send('/api/bill?bill=t&'+segmentUrl, {"operation": 'GET'})
         .then(function (response) {
              deferred.resolve(response.data); 
         }
         , function (error) {
              deferred.reject(error);
         });

  } 

  return deferred.promise;
}

[EDIT]

In response to @JC Ford's suggestion, considering that HttpWrapper already returns a Promise, we can simplify the logic as follows:

self.getBillInfo = function(array){

  if(array.length == 0){
     return $q.resolve([]); // return an empty list;
  }
  else{
    var segmentUrl = '';
    for(var i =0;i<idsArray.length;i++){
         if(i != (idsArray.length-1))
            segmentUrl += 'ids='+idsArray[i]+'&';
         else
            segmentUrl += 'ids='+idsArray[i];
        }
       return HttpWrapper.send('/api/bill?bill=t&'+segmentUrl, {"operation": 'GET'});        
  } 
}

Answer №2

Utilize the $q service within the getBillInfo() function to ensure accessibility. By wrapping a value in $q.resolve(), you create a promise that returns the specified value, which can even be another promise. In situations where the getBillInfo() function needs to terminate early without a value, return an empty $q.resolve() to guarantee the return of a promise.

this.getBillInfo = function(idsArray){

    //This results in undefined and triggers an error.
    if(!idsArray.length) return; 

    //This produces a promise that resolves immediately and executes the .then() handler.
    if(!idsArray.length) return $q.resolve();

    //This generates a promise that rejects immediately and executes the .catch() handler.
    if(!idsArray.length) return $q.reject(); 

    var segmentUrl = '';
    for(var i =0;i<idsArray.length;i++){
        if(i != (idsArray.length-1))
            segmentUrl += 'ids='+idsArray[i]+'&';
        else
            segmentUrl += 'ids='+idsArray[i];
    }
    return HttpWrapper.send('/api/bill?bill=t&'+segmentUrl, {"operation": 'GET'});
};

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

Automatically reload a particular webpage upon closing a pop-up window (using jQuery)

I am facing an issue with a pop-up named PopUp1 on page0.aspx. The problem occurs when a user clicks on a row in the GridView within PopUp1, causing another pop-up to launch, loading my page1.aspx. The complication arises when the user navigates through l ...

Tips for displaying a specific JSON element when using interpolation in Angular

How can I display a specific element from a JSON object using Angular interpolation? public responseData:any; renderTokenCard(){ this.mundipaggS.checkToken().subscribe((response:any)=> { console.log("success: ", JSON.stringify(res ...

"Troubleshooting issue with AngularJS ng-repeat order by functionality based on

I am currently trying to sort my ng-repeat by descending date order, with the newest items appearing first. Despite my efforts, I have been unable to achieve this. I have carefully checked for any errors in quoting, but still no luck. I've attempted ...

Tips for displaying an array of objects in a single <li> tag in React

I have an array with nested arrays structured like this: [Array(2), Array(2), ...] example Each subarray contains two objects with a "text" property. obj = {key: something, text: something} Now I am looking to render the "text" property of each subarra ...

Are there any methods for simultaneously hosting both React and vanilla JavaScript websites?

I want to host a full-fledged web application that is primarily implementing ReactJS, but also contains sections utilizing vanilla JavaScript. Is it possible to host a web app that combines both React and vanilla JavaScript functionalities? (My backend i ...

Is it possible to determine the outcome of a JavaScript function using Python?

I am currently in the process of creating a web crawler. Extracting links from HTML is simple, but finding links that are generated by JavaScript proves to be more challenging for me. Is there a way to access the JavaScript output in order to determine w ...

Struggling to store pushed data accurately into an array using node.js

) Currently, I am tackling a challenging node.js express custom API project. The issue arises when attempting to push data... This is the snippet of my code: module.exports = function(config, steamClient, csgo, database, teamspeakClient, router) { var a ...

Struggling to dynamically generate class names with clsx in combination with TailwindCss

Greetings! I am a JavaScript developer who is not very skilled yet, working with React and Next. Specifically, I am using this template When it comes to declaring component class names, I have been using a utility function that combines tailwind-merge and ...

Automatically populate select boxes with values from a different source using PHP

I'm in the process of setting up automatic population for 2 select boxes on a website. When a user chooses a class, the second select box automatically displays the main specialization of that class. If the user selects Tank (for example), the third ...

Difficulty encountered with document.querySelectorAll retrieving paginated elements

I am currently developing a project called STEEP. Our implementation involves utilizing infinite scroll to load 8 videos at a time as the user scrolls through the page. However, we are facing an issue with the script responsible for handling video playbac ...

What is causing the label's color to remain the same?

Once the page has loaded, the label color (which reads "enter your name") is supposed to change to red. However, despite the script being in place, the color remains unchanged. What could be the reason for this? SCRIPT window.onload = initiateScript; fu ...

Retrieve various objects from separate files using Node.js

Throughout the development of my Node.js project, which I have been working on since my teenage years and consists of a multitude of files, I have initialized numerous objects in the index.js file. This is also where all function calls originate. In order ...

Add an asterisk before each line of comment when working in a TypeScript file using the VS Code IDE

Within my VS Code workspace, I am using the Typescript language and would like to format my comments across multiple lines with a specific style (look out for the star character) /** *@desc any text * any text */ However, when I attempt to write a comm ...

Supporting multiple types for matching object structures is a feature in Jest

I'm currently working on a test using jest to verify if an object key is either a string or a number. It seems like a basic task, but surprisingly there isn't much guidance in the documentation. Test Example: test('Checking asset structure ...

Ensure mydesign is seamlessly integrated with the asp.net page

Recently, I've been working on an Asp.net page and here's a snippet of my code: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="fisrt_page.aspx.cs" Inherits="my_project.fisrt_page" %> <!DOCTYPE html> <html xmlns="http: ...

The attempt to register a ServiceWorker for the angular scope was unsuccessful

I have encountered various solutions to this issue, some of which are not suitable for Angular and others simply do not work. In my quest to implement the "add to Homescreen" feature, I came across a helpful blog post (https://blog.betapage.co/how-to-add ...

Obtain the IDs of the previous and next list items if they exist?

Hey there friends, I've hit a roadblock and could really use your help. I'm trying to figure out how to get the previous and next list items in a specific scenario. Let's say I have a ul with three li elements, and the second one is currentl ...

The Angular routing system is failing to display the designated view

I am trying to implement routeProvider within ngRoute in AngularJS to display different views such as home.html, delete.html, or add.html app.js var app = angular.module('MyApp', ['ngRoute']); MyApp.config([ '$routeProvider ...

How to insert an element INTO a JSON array using JavaScript

I'm having an issue with the way a line is displayed on my screen: Would you like to pay €xx to POS_ID Latte X 1....€2.50-Salad X 1....€4.00-Wrap X 1....€4.50-Coffee X 2....€3.00- My desired format is as follows: Would you like to pay ...

Innovative Inter-Browser Link with a Distinct Shape

I am currently developing a web application that enables users to input content and then send it out to their phones. Everything is working smoothly, but I am facing an issue with the logo design. The logo in question is displayed as follows: On the left ...