0

I have an API call that will respond a list, and I want to show a dialog box for each error, but I want the next dialog box(es) to display after I pressed Yes for the first one. How do I handle this? because for now, It continues to the loop even if there's no selected answer yet.

I've tried the answer from this Link but it didn't worked for me.

Any other way to handle this?

 timeSheetApi
    .validate(clonedTimesheet)
    .then(function (resp) {
     var validationErrors = resp.data;

     line.ErrorCount = 0;
     line.WarningCount = 0;
     line.Errors = "";

     if (validationErrors.length > 0) {
         line.ErrorCount = validationErrors.length;

         validationErrors.forEach(detail,index){
            let confirm = $mdDialog.confirm()
                          .title('')
                          .htmlContent(detail.Message)
                          .ok('Yes')
                          .cancel('No');

        $mdDialog.show(confirm).then(function(){
            //yes
            //i want the loop to wait for this yes
        }, function(){
            //no
            // and exit this loop if no was selected
        });
         }

         line.Errors = cleanErrorMessage(line.Errors);
         triggerOption(sourceColumn, prop, index, val, time_field);

         return line;
                }).catch(function (err) {
                exceptionService.resolve(err);
            });
JC Borlagdan
  • 3,318
  • 5
  • 28
  • 51
  • You have a syntax error in your code snippet, please go through it and correct it. It's probably near the ` validationErrors.forEach(detail,index){` code, and maybe other places, too. – Armen Michaeli Jun 17 '19 at 08:38

3 Answers3

1

You will have to refrain from showing your dialogs in the loop. Obviously, by the time your script has run, the loop would have iterated over all and every validation error, and you would have called show on every dialog you created in the loop, for every such error. That's why you have multiple dialogs being shown by the time script has completed.

What you can do is you can create and show each dialog only after the previous dialog has been closed. Observe a modified version of your script, where instead of looping through validation errors (with forEach), I stick to processing an error, showing a dialog for it, and upon closing said dialog, I continue to process the next error, reusing the same validationErrors array:

timeSheetApi
    .validate(clonedTimesheet)
    .then(function (resp) {
        var validationErrors = resp.data;

        line.ErrorCount = 0;
        line.WarningCount = 0;
        line.Errors = "";

        function process_next_error() {
            const next_error = validationErrors.shift();
            if(!next_error) return; /// No more validation errors
            let confirm = $mdDialog.confirm()
              .title('')
              .htmlContent(timesheetError.Message)
              .ok('Yes')
              .cancel('No');
            $mdDialog.show(confirm).then(process_next_error);
        }

        process_next_error();

        line.Errors = cleanErrorMessage(line.Errors);
        triggerOption(sourceColumn, prop, index, val, time_field);

        return line;
    }).catch(function (err) {
        exceptionService.resolve(err);
    });

The "handler" function above is the process_next_error function -- it's the one the script calls directly initially to process the first error, but also the one the script uses as the callback for the show(confirm) promise, which resolves when the dialog is closed.

When there are no more errors left, process_next_error just returns, doing nothing.

The validationErrors array will be empty by the time last dialog is closed, that's because I gradually "shift" items from it. I assume that's not a problem because something tells me validationErrors is a very transient variable in your application. If you want to retain the elements originally in the validationErrors array, you either take a copy of it, or iterate through it instead of using shift.

Armen Michaeli
  • 8,625
  • 8
  • 58
  • 95
0

You should use await there and used simple for loop. Foreach loop takes a callback and you received promise in it so it doesn't there.

Syed Afzal
  • 150
  • 1
  • 8
0

I think you should re-code it without using forEach. Here is the demo in which you can loop through each element without using forEach.

Asfan Shaikh
  • 759
  • 5
  • 9