Resetting the $q resolve state in AngularJS can help to ensure that promises

I am facing an issue with a service that runs an ajax query and then passes the response to another function for parsing. The initial function returns a promise using the $q library before it is resolved in the parsing function, which then passes the parsed object as a parameter to the resolve method. When my controller uses the .then method to log out the response, everything works perfectly the first time. However, on consecutive calls, it returns the resolve from the initial call before the second call. How can I prevent this from happening?

Below is the code snippet:

app.controller("login", ['$scope','XMLMC', function ($scope,api) {
    $scope.login = function() { 
    //This function is tied to an ng-click directive in the current route template
        var params = {
            selfServiceInstance: "selfservice",
            customerId: $scope.username,
            password: $scope.password
    };
        var authenticated = api.request("session","selfServiceLogon",params).then(function(response) {
            console.log(response); 
            //log the response once the promise is resolved or rejected
        });

    };
}]);


app.factory("XMLMC", ['$http', '$q', function ($http, $q) {
    function XMLMC($http, $q) {
        $http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
        var def = $q.defer();
        var P = def.promise;
        var that= this;

        this.prepareForPost = function(pkg) {
            return JSON.stringify(pkg);
        };

        this.request = function(service, request, params, host, newsession) {

            if(request === "analystLogon") {
                newsession = true;
            }

            var call = {
                service: service,
                method: request,
                params: params
            };

            if(host) {
                call.host = host;
            } else {
                call.host = "localhost";
            }

            if(newsession) {
                call.newsession = "true";
            }

            var pkg = {
                contents: this.prepareForPost(call)
            };




            $http.post('php/XMLMC/api.php', jQuery.param(pkg)).success(function (response,status) {
                    that.consume(response, def); 
                    //consume the response, pass the deferred object to resolve later

                }).error(function (response,status) {
                    def.reject(response,status);
                });

            return P; //return the promise, not the resolved object


    };

    this.consume = function(response, defer) {
        console.log(response);
        //log the response that was received.  For some reason this log happens after the log in the controller on subsequent calls to this service, not the first call.
        var resp = response[0],
            digested = {},
            i;

        digested.status = resp["attrs"]["STATUS"];
        var params = resp["children"][0]["children"];
        for(i=0; i < params.length; i++) {
            var key = params[i]["name"];
            var val = params[i]["tagData"];
            digested[key] = val;
        }

        defer.resolve(digested);
        //resolve at this point, after the response has been consumed and parsed.
    };
}

    return new XMLMC($http, $q);
    //return new instance of this object for ease of use in controller
}]);

Answer №1

Consider implementing this schema, where the creation of the deferred object is removed and the promise chain initiated by $http.post is returned. Although it's not guaranteed to work, it seems promising as $http returns a promise.

app.factory("XMLMC", ['$http', '$q', function ($http, $q) {
   function XMLMC($http, $q) {
    $http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;   charset=UTF-8';

    this.prepareForPost = function(pkg) {
        return JSON.stringify(pkg);
    };

    this.request = function(service, request, params, host, newsession) {

        if(request === "analystLogon") {
            newsession = true;
        }

        var call = {
            service: service,
            method: request,
            params: params
        };

        if(host) {
            call.host = host;
        } else {
            call.host = "localhost";
        }

        if(newsession) {
            call.newsession = "true";
        }

        var pkg = {
            contents: this.prepareForPost(call)
        };




        return $http.post('php/XMLMC/api.php', jQuery.param(pkg))
       .then(that.consume)

};

consume = function(response) {
    console.log(response);
    var resp = response[0],
        digested = {},
        i;

    digested.status = resp["attrs"]["STATUS"];
    var params = resp["children"][0]["children"];
    for(i=0; i < params.length; i++) {
        var key = params[i]["name"];
        var val = params[i]["tagData"];
        digested[key] = val;
    }

    return $q.resolve(digested);
    //resolve at this point, after the response has been consumed and parsed.
};

}

return new XMLMC($http, $q);
//return new instance of this object for ease of use in controller

}]);

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

What is the purpose of the 'onClassExtended' function in Extjs 6 for class definition?

Ext.define('Algorithm.data.Simulated', { needs: [ //.... ], onClassExtended: function(obj, info) { // .... } }) I came across this code snippet but couldn't locate any official documentation for it on Sencha ...

Updating an element within an array in a Mongoose database: A step-by-step guide

Currently, I'm looking to make updates to the "like" attribute within an array stored in my mongoose database. { "_id" : ObjectId("59c7eb0c4a992f8702d847a4"), "title" : "Favorite Rapper", "token" : "9b3fd295a1", "votes" : [ { ...

Show unique language text in the <noscript> element based on the user's browser language

I am just starting out with HTML, and I would like to show a message if JavaScript is disabled. To do this, I have placed the message within the <noscript> tag, which is working perfectly. <noscript> Need to enable Javascript. </noscript> ...

"Error 404: Issue encountered while trying to save data on Backbone

There seems to be an issue with the /:id portion of my URL; I'm having trouble getting my Mongoose and Backbone ID fields to align correctly. The console is showing this error message: POST http://localhost:8080/api/bears/:id 404 (Not Found) Below is ...

Learn how to quickly resolve the issue in nodejs where the new image automatically replaces the old one when added

I have successfully created a file to upload images, however the image name appears as undefined.jpg in this project. I am using the Express file upload middleware. *admin.js var express = require("express"); const productHelpers = require("../helpers/pr ...

What is the best way to find the product of each object in an array by the corresponding values in another array?

Searching for a solution to an issue I encountered while working on an assignment. The problem can be illustrated as follows: var arrOfObj = [{a:10 },{a:20},{a:30}, ......] var arrToMultiply = [2,4,6, .....] The expected result const result = [{a:10,resul ...

How can AngularJS be used to manipulate HTML elements, such as those identified by the id selector in jQuery?

Although I have experience with jQuery, I am new to AngularJS. Currently, I am working on a requirement that involves displaying a loading icon and message above a specific HTML element (like a DIV) when initiating an http request, and removing it once the ...

Significant delay in fetching model data for controller via XHR

My controller is designed to make an ajax call to retrieve its model, which is a 4.5k json containing a 2d array. This data is then used to create a combo displaying a series of labels in the html below: <select data-ng-controller="CGSimpleXHRComboCont ...

Testing the functionality of a video player using Protractor

Exploring the world of front end development is a new adventure for me, so please bear with me. I have created an HTML page that includes an embedded video using the HTML video tag as shown below: <video id=... class=...> <source src=... type ...

How can I annihilate the reveal effect in Foundation 6?

I've encountered a problem with initializing reveal in Foundation 6. Specifically, I'm attempting to create a new instance for #menu on medium and small screens and remove it on large screens. However, I'm running into issues removing the da ...

Determine the standard query path by parsing the RESTful URL (Remove the resource identifiers) using JavaScript

I have a URL structure designed in RESTFUL format, for example: GET /street/:streetName/house/:houseNumber or GET /street/:streetName/house/listings. The placeholders :streetName and :houseNumber represent specific resources. I am looking to extract the co ...

Issue with File Existence Resulting in ENOENT Error

Check out this gist for more information: https://gist.github.com/973e70bde8e6a530c489 I have encountered an interesting problem with two scenarios. In one scenario, I can parse a CSV file that is already on the box without any issues. However, in the oth ...

Is the choice of ' and " marks significant?

Similar Question: When to Use Double or Single Quotes in JavaScript Are single quotes valid in HTML/XHTML? When coding in XHTML, HTML, Javascript etc., is there a preference between using single quote (') or double quote (")? Does it make a d ...

What is the process of integrating Bootstrap into a Node project?

I recently set up a MEAN stack project using npm and am currently including Bootstrap via CDN: link(rel='stylesheet', href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css') However, I want to add Bootstrap using ...

Exploring AngularJS with $crypto and ng-options

I need help with my code. Here are the relevant parts: Angular Code: var app = angular.module('App',['mdo-angular-cryptography']); app.controller('AtvdCtrl', function($scope, $crypto, PassWD, $http){ $scope.frInEtAc ...

Automating Angular JS pages with IE10 using Selenium

Currently, I am working on a project that involves automating pages developed in Angular JS using Selenium. The tests are running smoothly in Firefox 25 on a Windows machine. However, when I attempt to run the same tests through IE 10, I encounter random f ...

Templating with Underscores: Revolutionizing token markers

When using out of the box underscore templating, the default markers for raw content are <%= %>, and for HTML escaped content are <%- %>. However, it is possible to change these markers by adjusting the template settings, for example: _.templ ...

Javascript - Accessing a specific element in an array using a variable

I am currently developing a webpage that interacts with a CGI backend. While the CGI backend is functioning well, my limited knowledge of JavaScript is making it hard for me to manage the results retrieved from AJAX JSON requests. Here's what I have: ...

Using Angular UI-Bootstrap typeahead within a table

Here's a straightforward question - how can I configure the typeahead feature to function in a table that is linked to a different table than the one my typeahead utilizes? For instance, suppose I have a foreign key in one table and I want users to b ...

Playing back an Audio object using JavaScript

I'm facing an issue with replaying an audio sound every time the game starts in my Cocos2d javascript code. The sound plays correctly the first time, but subsequent attempts to play it result in no sound being heard. Below is my code snippet: var my ...