Validation and promises in the world of AngularJS

Validation of a form in an Angular app involves using a custom JavaScript function before submission. Depending on a condition, a confirmation dialog needs to be displayed to the user, requiring them to confirm or reject it before proceeding with validation. However, I am struggling to achieve this asynchronously. It seems like I may not be utilizing promises correctly, but I'm unsure about what changes need to be made.

Factory

app.factory("confirmDialogService", ['$q', 'ngDialog',
  function ($q, ngDialog ) {
  return {
    popConfirm: function () {
        var deferred = $q.defer();
        var confirmed;
        setTimeout(function () {
                ngDialog.openConfirm({
                    template: 'template/confirmDialog.html',
                    className: 'ngdialog-theme-default'
                }).then(function (value) {
                    console.log('Modal promise resolved. Value: ', value);
                    deferred.resolve(confirmed =  true);
                }, function (reason) {
                    console.log('Modal promise rejected. Reason: ', reason);
                    deferred.reject(confirmed =  false);
                });
        }, 1000);
        return deferred.promise;
      }
  };
}]);

Controller

  $scope.checkSomething = function (){
    if(needsConfirmation)
    {
        console.log('about to pop confirm');
        confirmationService.popConfirm().then(function(confirmed){
            console.log( 'from popConfirm() ' + confirmed + ''); // never logged
            return confirmed;
        }, function(){
        // something went wrong
            return false;
        });
    }
    else
        return true;
}

Although the confirmation dialog is displayed, clicking yes or no does not produce the expected results.

I would like to obtain a true/false value based on whether the user confirms or dismisses the dialog, similar to:

var canProceed = $scope.checkSomething();

I believe I might need to wrap this in another promise, but I am uncertain how to do so. Any assistance would be greatly appreciated.

Thank you,

Answer №1

Instead of creating an additional promise with $q.defer(), you can simply utilize the Promise returned by openConfirm:

app.factory("confirmDialogService", ['$q', 'ngDialog', function ($q, ngDialog) {
    return {
        popConfirm: function () {
            return ngDialog.openConfirm({
                template: 'template/confirmDialog.html',
                className: 'ngdialog-theme-default'
            }).then(function (value) {
                console.log('Modal promise resolved. Value: ', value);
                return true;
            }, function (reason) {
                console.log('Modal promise rejected. Reason: ', reason);
                return false;
            });
        }
    };
}]);

The usage of checkSomething would be as follows:

$scope.checkSomething = function () {
    if (needsConfirmation) {
        return confirmationService.popConfirm().then(function (confirmed) {
            return confirmed;
        }, function () {
            return false;
        });
    } else {
        return $q.when(true);
    }
}

Now, instead of directly returning true or false, it returns a promise object. Therefore, you should treat $scope.checkSomething() as an asynchronous operation using promises:

$scope.checkSomething().then(function() {
    // Proceed with the operation
}, function() {
    // Handle any failures
});

To sum it up, remember that checkSomething must return a promise and not just boolean values.

Answer №2

In order to pass into the resolve and reject methods of a promise, you do not necessarily need a variable (although it will still work):

           .then(function (value) {
                console.log('Modal promise resolved. Value: ', value);
                deferred.resolve(true);
            }, function (reason) {
                console.log('Modal promise rejected. Reason: ', reason);
                deferred.reject(false);
            });

When dealing with this in the controller:

$scope.checkSomething = function (){
    if(needsConfirmation)
    {
        console.log('about to pop confirm');
        confirmationService.popConfirm().then(function(confirmed){
            console.log( 'from popConfirm() ' + confirmed + ''); // never logged
            return confirmed; <-- this is not(!) a return of checkSomething method, this is return of success callback
        }, function(){
        // something went wrong
            return false; //same as above
        });
    }
    else {
        return true;
    }
}

Therefore, you cannot simply assign the result of $scope.checkSomething() to a variable.

You must set this variable within the callbacks:

            var canProceed;
            confirmationService.popConfirm().then(function(confirmed){
                canProceed = true;
            }, function(){
            // something went wrong
                canProceed = false;
            });

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

comparison of declarative loop and imperative loop

In my journey to transition from an imperative programming style to a declarative one, I've encountered a challenge related to performance when dealing with loops. Specifically, I have a set of original DATA that I need to manipulate in order to achie ...

Utilizing jQuery to implement a function on every individual row within a table

I have a collection of objects that requires applying a function to each item, along with logging the corresponding name and id. Below is the snippet of my code: var userJson = [ { id: 1, name: "Jon", age: 20 }, { ...

Selecting the appropriate technology or library for incorporating user-defined text along a designated path within established areas

I am currently developing an admin dashboard with CodeIgniter 2 that allows the admin to upload custom images, particularly ones with blank spaces for text overlay. The goal is to enable regular users to add their desired text in specific areas defined by ...

Dragging items in the horizontal list of Knockout-Sortable causes them to be pushed vertically

For my application development using knockout.js, I am implementing knockout-sortable to create drag-and-drop sortable lists. The setup involves a vertical list with each item containing a horizontal list. While the vertical lists are functioning properly, ...

How can I store a value or text to track view counts or a counter efficiently?

Recently, I've been trying to implement a view counter on my website, similar to what you see on YouTube. Currently, the number of views stands at 23. I managed to find some code that allows me to increment the view count every time I click on an imag ...

Issue with Chart.js V3.20: Struggling to Filter Legend Labels

Building a dynamic line chart using Chart.js with the capability of up to 19 datasets. The issue arises when there are less than 19 datasets, as the legend still displays for these unused datasets. Previously, a function was used in Chart.js 2.6.0 options ...

Using ngMock in Protractor should only be done in a testing environment

We are transitioning our protractor E2E tests for an Angular app to ngMock in order to mock our resources/http calls. However, I am struggling to find a suggested approach for loading ngMock in this situation. I want to avoid including the script directly ...

Combining meanings within a geometric interface

When setting up my routes, I like to include an additional field in the configuration. This is how I do it: app.config([ '$routeProvider', ($routeProvider: ng.route.IRouteProvider) => { $routeProvider ...

The request from localhost:3000 to localhost:3003 could not be proxied by ReactJS

Currently, I am working on developing a Single Page Application (SPA) using create-react-app with an expressjs server as the backend. During development, my frontend test server runs on port 3000 while my backend expressjs test server runs on port 3003. T ...

What is the connection between importing and using destructuring in ES6 syntax?

Bring in: import React, { Component } from 'react'; Unpacking: let z, { b } = {a: 1, b: 2, c: 3} Both of these examples seem to have similar syntax. However, in the second example, z will be undefined instead of {a: 1, b: 2, c: 3}. Does this ...

`Stop the JW Player from playing several videos simultaneously`

I have a situation where I want to display multiple videos on the same page, but only one should be playable at a time. When a new video is started, the currently playing video should automatically stop. <div class="tab-pane active" id="abc"><d ...

Error: Unexpected character encountered

When attempting to parse an array of objects enclosed in double quotes, I encountered an error: Uncaught SyntaxError: Unexpected token ' var test = "[{'key' :'D', 'value': 'Deceased Date'},{'key' ...

JavaScript node.js JSON Arrays

I am facing a challenge with an array of JSON data. After decoding the JSON, I need to save it as JSON again and send it across but I am unsure about the correct way to do so. Can someone guide me on using 'for' loops and promises to resolve this ...

Extract token from the URL and then use Axios in Vue.js to send it to the POST API

Hey there, I'm in need of extracting a token from the URL http://192.168.178.25:8080/register?token=eyJhbGciOiJIUzI... and then making a POST request to the API to confirm the account. I've attempted this but encountered a SyntaxError on the ...

There was an unforeseen conclusion to the JSON input while attempting to parse it

I am having an issue with the code in my get method. Can someone please help me troubleshoot and provide some guidance on how to solve it? app.get("/",function(req,res) { const url = "https://jsonplaceholder.typicode.com/users" ...

Tips for iterating through/range over an array depending on the initial point?

var ZODIAC = ["RAT", "OX", "TIGER", "RABBIT", "DRAGON", "SNAKE", "HORSE", "SHEEP", "MONKEY", "ROOSTER", "DOG", "PIG"]; var STARTING_ZODIAC = "MONKEY"; Is there a way to output the elements in the array that start with Monkey and end with Sheep? ...

Combining AngularJS with Bridgeit.js for a seamless mobile web app experience

Currently, I'm working on an AngularJS web application that requires scanning a package from a mobile device. To achieve this functionality, I am utilizing BridgeIt. Unfortunately, the code I've written in Angular doesn't seem to be functio ...

The filter predicate function is failing to produce a result and the following error occurs: Unable to access the 'data' property in MatTableDataSource within

There seems to be an issue with the function that is causing it to not work correctly the first time a letter is entered in the search bar. It returns nothing in the array initially, but works fine when letters are removed and typing continues. createFilt ...

Encountering an issue with resolving a local variable during the execution of a test with Protractor

I'm currently learning about async calls in protractor as a newbie to the tool. I am struggling to figure out how to handle a boolean variable that I set to true if any test case fails and the execution goes to the catch block for a promise. Below is ...

Node.js's async functions seem to be running sluggishly

My list of queries is all set and ready to go: var array = [ 'UPDATE EVALUATION SET mark = "16" WHERE id_eval = "21" AND id_usr = "125"', 'UPDATE EVALUATION SET mark = "9" WHERE id_eval = "22" AND id_usr = "125"', ...