The Angular promise refuses to resolve at my desired time

I am struggling with managing Angular promises in order to control when they resolve. In the code snippet below, my intention is to first retrieve KeyDataFromServer() and then proceed with executing the remaining commands only after all the keys have been loaded from the server. However, the current setup results in the other commands being executed and displayed in the view before the data is actually retrieved from the server. How can I correct this?

What could be causing the issue in my implementation?

// controller (with $q and KeyGenerationService injected)

$scope.KeyData = null;

var defer = $q.defer();
var promise = defer.promise;

promise
  .then(
    function() {

      var KeyData = {
          Server: KeyGenerationService.getKeyDataFromServer()
        };

      return KeyData;

  })
  .then(
    function(KeyDataFromFunction1) {

      var KeyData = {
          KeyDateGroup: KeyGenerationService.generateKeyDateGroup(),
          KeyID: KeyGenerationService.generateKeyID(),
          Server: KeyDataFromFunction1.Server
      };

      return KeyData;

  })
  .then(
    function(KeyDataFromFunction2){

      $scope.KeyData = KeyDataFromFunction2;

  })
  .catch(
    function(error){
      window.alert(error);
    })

defer.resolve($scope.KeyData)

// factory

.factory('KeyGenerationService', function($q, fbutil) {

        // operations
        return {

            generateKeyDateGroup: function() {

                var today = new Date();
                var d = today;
                var dd = today.getDate();
                var mm = today.getMonth()+1; 
                var yyyy = today.getFullYear();
                if(dd<10) {
                  dd='0'+dd
                } 
                if(mm<10) {
                  mm='0'+mm
                } 
                today = yyyy+''+mm+''+ dd;

                return today;

            },

            generateKeyID: function() {

                var d = new Date().getTime();
                var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
                  var r = (d + Math.random()*16)%16 | 0;
                  d = Math.floor(d/16);
                  return (c=='x' ? r : (r&0x3|0x8)).toString(16);
                });

                return uuid;

            },

             getKeyDataFromServer: function() {
                return fbutil.syncArray('keys');
            }

        } // return

    }) // .factory KeyGenerationService

Answer №1

Your approach to using promises needs some adjustment. In order to properly handle promises, it's best for the controller to receive the promise, while async calls should be responsible for creating, resolving, and rejecting them.

One key issue is determining if fbutil.syncArray is a synchronous call or not. While the name suggests synchronicity, HTTP requests like get/post are typically asynchronous. Hence, understanding what this call returns is crucial.

To improve the structure so that the Service takes charge of promise creation, consider this:

.factory('KeyGenerationService', function($q, fbutil) {

        // Functions
        return {

            generateKeyDateGroup: function() {
                // Synchronous function
                var today = new Date();
                var d = today;
                var dd = today.getDate();
                var mm = today.getMonth()+1; 
                var yyyy = today.getFullYear();
                
                if(dd<10) {
                    dd='0'+dd
                } 
                if(mm<10) {
                    mm='0'+mm
                } 
                today = yyyy+''+mm+''+ dd;

                return today;
            },

            generateKeyID: function() {
                // Another synchronous function
                var d = new Date().getTime();
                var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
                    var r = (d + Math.random()*16)%16 | 0;
                    d = Math.floor(d/16);
                    return (c=='x' ? r : (r&0x3|0x8)).toString(16);
                });

                return uuid;
            },
            
            getKeyDataFromServer: function() {
               // Asynchronous function requiring promises
                var defer = $q.defer();

                var result = fbutil.syncArray('keys');
                defer.resolve(result);

                return defer.promise;
            }

        } 

    }) 

The simplified controller code would look like:

$scope.KeyData = null;

KeyGenerationService.getKeyDataFromServer().then(
    // Success handler
    function(result){
        $scope.KeyData = {
            KeyDateGroup:     KeyGenerationService.generateKeyDateGroup(),
            KeyID:            KeyGenerationService.generateKeyID(),
            Server:           result
        };
    },
    // Error handler
    function(error){
      window.alert(error);
    }
);

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

Is there a way to prevent a bootstrap modal from opening?

Recently, I encountered an issue with a button on my webpage: <a data-toggle="modal" href="#influencerModal" class="btn btn-primary influencer-card">Influencer Profile</a> I wanted to prevent the modal from opening when the button was clicked ...

Is there a way to eliminate the 'All Files' option from an HTML file input field?

I have implemented a feature to allow users to upload custom files using . Currently, I am restricting the allowed file types to only ".Txt, .SVG, .BMP, .JPEG" by using accept=".Txt,.SVG,.BMP,.JPEG". This setting causes the browser's file-select dial ...

Guide for transferring information from JavaScript to PHP on the same page

My dilemma lies in transferring data from my JavaScript script to PHP code for use within a query. Despite numerous attempts, I have been unsuccessful in achieving this. Below is my script for uploading files using an input type: file, where the URL is sto ...

Basic image manipulation features integrated with AngularJS

Looking to incorporate some light image layering, scaling, and positioning within a specific box on an AngularJS enabled web page? What is the recommended approach or convention for achieving this functionality? Is using jQuery the best option for impleme ...

The error occurred in async JavaScript parallel code because the task is not recognized as a function

I am attempting to upload an image and update the image URL in the database collection using the code provided below. Controller.prototype.handle = function (req, res, next) { var id = req.params.id, controller = req.params.controller, optio ...

Is there a way to print messages to the console of openDevTools in Electron JS?

After finishing a hello world application using electron js, I have successfully printed to my terminal with console.log and opened the openDevTools in the window of my application. However, I am now interested in finding a way for my console.log stateme ...

Encountering issues with the hyperlink tag '<a>' in an HTML document

I've encountered an issue with the code on my HTML page: <body> <div align="center"> <a href="../index.html"> <img border="0" src="banner1.jpg" width="800" height="120" alt="Ecommerce Knowledge Base"> &l ...

AngularJS $http get isn't functioning properly, but surprisingly $.ajax works perfectly

Recently delving into the world of AngularJS, I am facing a hurdle with $http functionality. In my factory setup below: app.factory('employeeFactory', function ($http) { var factory = {}; // Retrieving data from controller var emplo ...

Prevent the upward arrow from appearing on the first row and the downward arrow from appearing on the last row when

This is a straightforward question, but I'm unsure how to achieve it. I am currently working on sorting columns using jQuery. $(document).ready(function(){ $(".up,.down,.top,.bottom").click(function(){ var row = $(this).parents("tr:f ...

What are alternative methods to exchange data between two controllers besides using services and rootscope?

In a recent interview, I was asked about sharing data between two controllers in Angular. I'm familiar with using services and root scope for this purpose. However, I'm curious if there's an alternative method to pass data between controller ...

Using val() on a checkbox will give you an element, not a string literal

How can I retrieve only the literal values of all checked checkboxes without any additional data? My current approach is: $('input:checked').map(function() { return $(this).val(); }) The result that I am getting looks like this: e.fn.init[1]0 ...

When using HTML5's checkValidity method, it may return a valid result even if

Consider the following scenario: <input pattern="[a-z]"/> If you run the command below without entering any input: document.querySelector('input').checkValidity() You will notice that it actually returns true. This seems counterintuiti ...

Having trouble getting this JavaScript query to function properly

The initial div in the code snippet below showcases the name of a university. When this name is clicked, it activates the function display_people(). This function is responsible for displaying or hiding the individuals associated with that university. The ...

Combining Two Validation Methods for jQuery Validate Plugin

Seeking advice on how to incorporate custom validation methods from jQuery validate into another method for validating data. Specifically, I have a 'Document ID' field that can accept either CPF or CNPJ (Brazilian documents) and I need to validat ...

Steps for deactivating a textbox upon checkbox activation

When I try to implement the instructions from the textbook, I'm encountering an issue where clicking on the checkbox doesn't disable the textbox on my website. <form action="#"> Billing Address same as Shipping Address: <input ...

Issue: The function (0, react__WEBPACK_IMPORTED_MODULE_1__.useActionState) is not recognized as a valid function or its output is not iterable

I found a great example of using useActionState at this source. Currently, I am implementing it in my project with Next.js and TypeScript. app/page.tsx: "use client"; import { useActionState } from "react"; import { createUser } from ...

Analyzing user input against specific fields within an array of JSON objects

My webserver contains JSON data structured like this: [ { iduser: 1, username: "joe", password: "****" }, { iduser: 2, username: "gina", password: "****" } ] When users input their information in my app, I aim to compare i ...

How to alter row colors in SQL/PHP tables

echo "<tbody"; echo "<tr>"; echo "<td>{$id}</td>";// display customer Id echo "<td> {$firstname} {$lastname}</td>"; //display customer title,firstname,lastname echo "<td>{$date->format('h:i A')}</td> ...

Ways to effectively pass arguments to the callback function within the catch function in JavaScript

While working on my code, I suddenly felt the need to pass an extra argument, "msg", to the callback function renderError(). This extra argument should be passed along with the default error argument generated by the catch function itself. I tried doing i ...

Methods to modify the state of a Modal component beyond the boundaries of a React class

I am attempting to trigger my modal by modifying the state from outside of the react class. Unfortunately, I have had no success thus far. I have experimented with the following approach: In my code, I have a method named "Portfolio" that is responsible f ...