Effectively handling nested promises in angularJS to construct a cohesive server response

When building a response back from the server using Angular to display private messages, I've come across code that seems to work fine but may not be following best practices for handling promises and errors. How should nested promises be handled in such cases to ensure best practices are being followed?

function listenMessageSend(data) {

var imData = {
  message: data.data.id,
  sender: currentUser().id,
  reciever: $scope.reciever
}

Im.create(imData).then(function(im) {
  Message.update(im.data.message, {im: im.data.id}).then(function(msg) {
    User.get(msg.data.im.sender).then(function(sender) {
      msg.data.im.sender = sender.data;
      User.get(msg.data.im.reciever).then(function(reciever) {
        msg.data.im.reciever = reciever.data;
      });   
    });
    if (msg.data.im.sender === currentUser().id || msg.data.im.reciever === currentUser().id) {
      $scope.messages.push(msg.data);
    }
  })
});

};

Answer №1

To optimize performance and improve user experience, it is recommended to fetch sender and receiver data simultaneously instead of nesting two independent promises. By issuing both requests at the same time, the browser can handle them concurrently without waiting for one to finish before starting the other.

Consider restructuring the code like this:

Im.create(imData).then(function(im) {
  Message.update(im.data.message, {im: im.data.id}).then(function(msg) {
    var senderGet = User.get(msg.data.im.sender);
    var receiverGet = User.get(msg.data.im.reciever);
    $q.all([senderGet, receiverGet]).then(function(response) {
      msg.data.im.sender = response[0].data;
      msg.data.im.reciever = response[1].data;      
      if (msg.data.im.sender === currentUser().id || msg.data.im.reciever === currentUser().id) {
        $scope.messages.push(msg.data);
      } 
    });
  })
});

Answer №2

The if statement needs to remain within the inner promise in order to be resolved last:

User.fetch(msg.data.im.sender).then(function(sender) {
  msg.data.im.sender = sender.info;
  User.fetch(msg.data.im.reciever).then(function(receiver) {
    msg.data.im.receiver = receiver.info;
    if (msg.data.im.sender === getCurrentUser().id || msg.data.im.receiver === getCurrentUser().id) {
      $scope.messages.push(msg.data);
    }
  });   
});

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

Utilizing database information to dynamically select Nightwatch.js tests for execution

Currently, I am in the process of configuring nightwatch tests for a specific website. The setup involves assigning testing personas to run tests, which works smoothly in our development environment. However, we face an issue when we need to dynamically ad ...

Javascript does not function on sections generated by ajax

I'm facing an issue with a JavaScript function not working on a dynamically generated part using AJAX. Here is the AJAX call: <script> $(window).on('scroll', function() { $("#preloadmore").show(); if ($(window).height() + $(window ...

Custom AngularJS directive for validating date input forms

My current project involves an Angular 1.5.3 app. This is the task at hand: I have a user form with two date input fields. I need to implement custom validation on the form so that if the "expiry date" is greater than the "effective date", an error messa ...

Unable to scroll horizontally beyond 200 viewport widths

I'm facing an issue with my code that switches between vertical and horizontal scrolling but seems to have a width limit of 200vw. When I set the min-width to 50vw, only 4 sections are visible, whereas setting it to 100vw (as shown in the example) dis ...

An unexpected hiccup occurred in the processing of the Ionic action! We are now working to

While working on my project for Android, I encountered an issue when running "ionic build android" or "ionic emulate android." The error message displayed was as follows: Error during processing of action! Attempting to revert... Error: Uh oh! Invalid Ver ...

Is there a way to keep the selected option in handlebar permanently, even after multiple page refreshes?

I am having trouble implementing the drop-down menu option in handlebars using jQuery. Therefore, I have opted to use the select-options menu instead. Here is the code snippet: <select name="sources" id="sources" class="custom-s ...

Submit a form using AJAX validation with either jQuery or vanilla JavaScript

As a .NET coder with little (no) front-end experience, I must apologize upfront. Upon clicking Submit, the form should trigger a call to a REST service. If the service response is true, a warning about a duplicate entry should be displayed, and the user s ...

Navigating following a JQuery AJAX request in PHP

After clicking the login button, I utilize JQuery's POST method to retrieve data from login.php to check if the login was successful. If it fails (no user found), the appropriate message is displayed. However, when attempting to redirect a user (whic ...

Unable to execute multiple queries within a CloudCode query

In my quest to discover new users who I have not connected with before using a cloud function, I am utilizing several tables: Users table - This standard table includes an additional "hasLight" boolean column Connected table: 'user' - a point ...

A class member is not permitted to include the 'const' keyword

Having trouble with my ts code as I try to create a constant that can be easily changed by just modifying a simple element - but keep encountering the error that says "A class member cannot have the 'const' keyword." Here's the code snippet ...

What tool can be used for formatting and syntax highlighting when working with ejs (embedded javascript) templates?

When working on my project, I utilize EJS as the express templating engine. While it is user-friendly and efficient, I have encountered difficulties when it comes to editing files - the text highlighting could be better, and I have not been able to find an ...

Exploring the Power of Asynchronous Operations with Await and Async in

I have a basic understanding of how to use await/async in Angular 2 with the following example: async getValueWithAsync() { const value = <number>await this.resolveAfter2Seconds(20); console.log(`async result: ${value}`); } In my Angular ...

Convert an array containing arrays of booleans to a single array of booleans (Array<Array<boolean>> to Array<boolean>)

There is an array that contains multiple arrays of booleans, all of the same length. arrBefore = [arr1, arr2, ..., arrn]; The goal is to create a new array that consists of boolean values where each index is true if any of the corresponding indexes in th ...

Leveraging Discord.js to retrieve all messages sent while the bot was inactive

My plan is to create a bot that will store all messages sent in a channel into a txt file on my computer. However, the challenge is that since my computer is not always on when the bot is running, there are gaps in the stored messages in the .txt file. I a ...

Is it possible to change the input type of 'time' to a string when utilizing ng-change in AngularJS?

Is there a way to convert a time input into a string or a timestamp for Firebase support? For instance, the code below will not function correctly due to the time input type. HTML <html ng-app='app'> <head> <script src="http ...

Is there a way to distinguish between a request from prerender.io (crawlers) and a real user (browser) using JavaScript?

I needed to identify whether requests were coming from prerender.io (a library used for rendering AngularJS applications for web crawlers) or from real users. If the request was from prerender, I had to redirect to a page specifically designed for SEO purp ...

Using socket.io and express for real-time communication with WebSockets

I'm currently working on implementing socket.io with express and I utilized the express generator. However, I am facing an issue where I cannot see any logs in the console. Prior to writing this, I followed the highly upvoted solution provided by G ...

Tips for creating gaps between list items in a collapsible navbar

I am attempting to add spacing between the li items in my collapsible navbar However, the issue arises when I slightly minimize the browser window, causing the navbar to collapse incorrectly. See image below: https://i.sstatic.net/TdKb4.png Below is t ...

Click on the ng-click attribute to access the HTML page

I need a button that can perform the following tasks: Execute multiple functions from the controller using ng-click(they must be called in HTML) Direct to another html page located in "static/page.html" onclick, when used for navigation (location.hr ...

Using a Handlebars function in JavaScript to appropriately format currency

In my handlebar template, I have the following code snippet: <span class="currencyFormatMe">{{_current_price}}</span> Here is an example of the output from the loop: Bid: $24000 I'm trying to format this output with commas and encounte ...