Dealing with nested promises: strategies for success

As someone who is new to the concept of promises and how they work, I have been trying to understand how to create and implement them in my code. Although I have read documentation on the topic and grasp the idea behind a promise, I am struggling with actually using them in my code.

Here is a simplified version of my code:

function start_it_all(){
    return $cordovaSQLite.execute(db, "SELECT foo FROM bar").then(function(result) {
        return anotherFunction();
    });
}
function anotherFunction(){
     return $http.get('foo.php').then(function(){
        // Here I get some data
     });
 }

Both the $cordovaSQLite and the $http functions are asynchronous. My goal is to be able to do this:

start_it_all().then(function(){
   // Hide Loading animation (no further return data needed).
});

I understand that the .then() function is used as a promise handler. However, as it currently stands, my code only returns the promise of the query from $cordovaSQLite. I want the promise of $http to be returned as well. This is where I encounter the error:

TypeError: Cannot read property 'then' of undefined
when calling start_it_all().then().

If anyone could provide guidance on how to achieve this, I would greatly appreciate it.

Answer №1

You do not need to nest those promises, you can simply follow this approach:

function start_it_all(){
    return $cordovaSQLite.execute(db, "SELECT foo FROM bar")
    .then(function(result) {
        return $http.get('foo.php');
    })
    .then(function(){
            // Here I retrieve some data
    });
}

According to the comments in the original question, the .then method of $cordovaSQLite.execute may not be Promise/A+ compliant

To resolve this issue, wrap $cordovaSQLite.execute(...) in Promise.resolve

function start_it_all(){
    return Promise.resolve($cordovaSQLite.execute(db, "SELECT foo FROM bar"))
    .then(function(result) {
        return $http.get('foo.php');
    })
    .then(function(){
            // Here I get some data
    });
}

Now, based on the comment and edited question

function start_it_all(){
    return Promise.resolve($cordovaSQLite.execute(db, "SELECT foo FROM bar"))
    .then(anotherFunction)
    .then(function(){
            // Here I get some data
    });
}

As @LenilsondeCastro pointed out - in angular, you can use $q.when instead of Promise.resolve

Answer №2

Ensure that you return the promise at each level of the chain, and return the data at the deepest level. So your code should look like this:

    return $http.get('foo.php').then(function(){
        // Fetching data here
        return data;
    });

Note: the above was written before the addition of the return.

In the main call, if you need to access the data, include it as an argument:

start_it_all().then(function(data){
   // Hide Loading animation.
});

Dealing with Errors

You mentioned receiving the execute promise in a comment, which could suggest an error preventing the HTTP request. To ensure all errors are caught, add error handlers:

function start_it_all(){
    return $cordovaSQLite.execute(db, "SELECT foo FROM bar").then(function(result) {
        return anotherFunction();
    }, function(err) {
        console.log('error in SQL query', err);
    });
}
function anotherFunction(){
     return $http.get('foo.php').then(function(){
        // Fetching data here
        return data;
     }, function(err){
        console.log('error occurred in HTTP request', err);
     });
 }

start_it_all().then(function(){
    // ...
});

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

<head> Javascript codes are failing to run

Currently utilizing JQuery Mobile, my goal is to navigate between pages with minimal script loading each time a page loads. Essentially, I want to import all the general scripts (such as JQuery.js, jquery_mobile.js, main.js, etc.) ONCE for all pages. In m ...

Loading a page with an Ajax form submission

Currently, I am in the process of developing a test script for a small website project. The main challenge I have encountered is troubleshooting a form within this project. To receive a response, I must complete a 5-step form wizard and then wait for the o ...

After upgrading to version 4.0.0 of typescript-eslint/parser, why is eslint having trouble recognizing JSX or certain react @types as undefined?"

In a large project built with ReactJs, the eslint rules are based on this specific eslint configuration: const DONT_WARN_CI = process.env.NODE_ENV === 'production' ? 0 : 1 module.exports = { ... After upgrading the library "@typescript-es ...

Enliven the character limit reaction by incorporating a thrilling shake animation when it reaches

I have implemented a feature in my component where if a user reaches the character limit, the component should shake. However, despite my efforts, the shaking effect is not working in the current code. const useStyles = makeStyles(() => ({ shake ...

Ajax Syntax Error: Unexpected Token U

I have been struggling all day with an issue while trying to send json data via ajax to Express. Here is how my ajax code looks like: $('#saveClause').click(function () { var username = document.getElementById('postUserName').inne ...

The functionality of reordering columns, virtual scrolling, and resizing the grid in jqgrid are not functioning properly

Implementing jqgrid with Symfony to display a datagrid has been a challenging task for me. Thanks to Oleg's insightful response, many of the major issues have been resolved. Below is a snippet of my code: <link rel="stylesheet" type="text/css" ...

Can you explain the error message "a.split is not a function" in an Angular context?

My Angular application is encountering an error upon page load. The error message displayed is as follows: angular-amin.js:122 TypeError: a.split is not a function at r (angular-amin.js:186) at m.$digest (angular-amin.js:145) at m.$apply (angular-ami ...

Unable to determine state1 within the context of state2

Transitioning from one state to another is done using $state.go() as shown below: $state.go('menuItem.list'); This action results in the following error: Could not resolve 'menuItem.list' from state 'branches.view' Shown b ...

Developing cross-platform code using AngularJS

Our tech stack includes Angular with Bower and a Python API. We operate in multiple environments such as dev, staging, and prod. Currently, we manually adjust connection strings on the front-end after deploying fresh code to match the specific environment. ...

Tips for utilizing navigator.getDisplayMedia with automatic screen selection:

navigator.mediaDevices.getDisplayMedia({ audio: false, video: true }).then(gotMedia).catch(function(e) { console.log('getDisplayMedia() error: ', e); }); Triggering the above code will result in a popup like this. There is anoth ...

Utilizing Vue Router to leverage specific getters from Vuex

I am currently facing an issue with accessing the authenticated user in my Vuex store within my router.js file. { path: '/admin/login', name: 'admin-login', component: AdminLogin, beforeEnter(to, from, next) { console.log(s ...

What is the most effective method for displaying two external web pages next to each other?

Looking for a solution to display an English Wikipedia article on the left side of the page alongside its Spanish version on the right side. Wondering if it's possible using HTML, JavaScript, AJAX, etc. I am aware that I could use iframes, but I woul ...

Unable to reach the sub-component of the JSON object that was returned

For some reason, I can't seem to access a sub object of a returned $Resource object that fetched a group of JSON objects. It's baffling me. Resource > $resolved: true > $then: function (b, g) {var j=e(),h= > data: Object > 519bc5f6 ...

javascript - audio is not working on the web

I've been trying to incorporate sound into my website using this code. Strangely, the sounds only seem to play in Adobe Dreamweaver and not in any browsers. Any advice would be greatly appreciated! :) var audio1 = new Audio('sound1.mp3'); v ...

Building a Modular Socket.io System using Express 4

I'm currently working on modularizing my application files, and I've encountered a challenge with the integration of Socket.io. My goal is to utilize io within my routes.js file. Here's an example of what I'm attempting: var router = r ...

Internet Explorer causing trouble with reliable Ajax dropdown selection

There are two drop-down lists on my website, where the options in one depend on the selection in the other. The Ajax code works perfectly fine in Chrome and Mozilla, but it's not functioning correctly in Internet Explorer (specifically IE9). I need so ...

header width not meeting 100% requirement

Take a look at this site: If you resize the window to the point where a horizontal scrollbar appears, then drag that scrollbar to the right, you'll notice an issue. The header and footer do not adjust properly. In the css file, the header and footer ...

Displaying Bootstrap Alert for a single occurrence

One issue I'm facing involves setting up alerts with Bootstrap. Initially, these alerts are hidden from view. However, when a rating is submitted using raty, an Ajax request is triggered. Upon successful completion of the request, an alert is displaye ...

The formcontrol for Reactive Forms is displaying the selected option as "Object object"

Within my component, I have the member Store array declared as follows: stores: Store[] The Store interface is defined as: export interface Store{ store_name: string; owner: string; display_name?: string; } In the HTML template, there is a select e ...

Is there a way to cycle through an array with each click?

I am currently working on implementing a slider feature that enables users to navigate through different pieces of information by clicking on arrows. However, I have encountered an issue where one arrow works correctly (forward), but the other arrow does n ...