admin管理员组

文章数量:1328599

I am new to Promises and I am sure I am doing something wrong with my code. The result is correct but I have an Uncaught (in promise) warning in my console.log. What is going on here is the User can submit a form where there are some required fields, some optional fields and an image. On submit I am getting the image that gets pressed, resized and oriented so that it upload to the server as a small amount of Kbs.

In the coontroller I validate the code as said, some fields are required so in the error case inside the Ajax call I get the textStatus if a field is missing.

What happens with this code is that if the user inputs the image but none or some of the required fields the XHR textstatus error object appears as Uncaught (in promise), (The missing required fields).

I am missing the point of how you deal with errors (reject ? ) in promises so I don't really know how to solve this one.

My guess is that if the User submits the image but not the required fields there should be a way to check that during the promise so that it gets rejected even if the user submitted the image (as the image alone does not suffice). Is this done with reject ? But where? and how do you call the error after .then() ? And what if the user submits some required fields or all of them but not the image? If I let the promise run I get an undefined error in the promise, that's why I added a check to see if there's any file and if it's an image.

This is my script:

$(document).ready(function () {

    $("#AddModel").on("submit", function (e) {

        e.preventDefault();

        // gets the file from the form input
        var files = $('#modelpic').prop('files');

        var form = $(this);

        // this strips the submitted form from the file and returns a new form with all the
        // inputs but the file
        var processedFormData = noFileFormData(form[0]);

        // only if there's a file and it's an image
        if( files.length !== 0 && /^image/.test(files[0].type)){

            //this calls the promise that manipulates the image and returns a blob
            processImage(files[0]).then(([img, ia])=> {

                processedFormData.append('image', ia, 'processed.jpg');

                return $.ajax({
                    type: 'POST',
                    url: form.prop('action'),
                    processData: false,
                    contentType: false,
                    cache: false,
                    data: processedFormData,
                    success: function (data) {

                        //displays preview of the post

                    },

                    error: function (textStatus) {

                        //displays errors


                    }
                });

            });
        }else{

                //displays an error re the image is not present.
                // Now this is not optimal as the image is not the only required field

        }
    });
});

This is the promise function that prepares the manipulated image, it calls some other functions for the real processing:

function processImage(file) {

    return new Promise(function (resolve, reject) {

        if (file.type.match('image.*') && file.length != 0) {

            var reader = new FileReader();

            reader.readAsDataURL(file);

            reader.onloadend = function () {

                var base64img = this.result;

                var exif = EXIF.readFromBinaryFile(base64ToArrayBuffer(this.result));
                var srcOrientation = exif.Orientation;

                resetOrientationResizeCompress(base64img, srcOrientation).then((img)=> {

                    dataURItoBlob(img).then((ia)=> {

                        resolve([img, ia]);

                    });

                });
            };
        }else{

            //don't really know what to do here really, or if this is the way

            reject();

        }
    });
}

I am new to Promises and I am sure I am doing something wrong with my code. The result is correct but I have an Uncaught (in promise) warning in my console.log. What is going on here is the User can submit a form where there are some required fields, some optional fields and an image. On submit I am getting the image that gets pressed, resized and oriented so that it upload to the server as a small amount of Kbs.

In the coontroller I validate the code as said, some fields are required so in the error case inside the Ajax call I get the textStatus if a field is missing.

What happens with this code is that if the user inputs the image but none or some of the required fields the XHR textstatus error object appears as Uncaught (in promise), (The missing required fields).

I am missing the point of how you deal with errors (reject ? ) in promises so I don't really know how to solve this one.

My guess is that if the User submits the image but not the required fields there should be a way to check that during the promise so that it gets rejected even if the user submitted the image (as the image alone does not suffice). Is this done with reject ? But where? and how do you call the error after .then() ? And what if the user submits some required fields or all of them but not the image? If I let the promise run I get an undefined error in the promise, that's why I added a check to see if there's any file and if it's an image.

This is my script:

$(document).ready(function () {

    $("#AddModel").on("submit", function (e) {

        e.preventDefault();

        // gets the file from the form input
        var files = $('#modelpic').prop('files');

        var form = $(this);

        // this strips the submitted form from the file and returns a new form with all the
        // inputs but the file
        var processedFormData = noFileFormData(form[0]);

        // only if there's a file and it's an image
        if( files.length !== 0 && /^image/.test(files[0].type)){

            //this calls the promise that manipulates the image and returns a blob
            processImage(files[0]).then(([img, ia])=> {

                processedFormData.append('image', ia, 'processed.jpg');

                return $.ajax({
                    type: 'POST',
                    url: form.prop('action'),
                    processData: false,
                    contentType: false,
                    cache: false,
                    data: processedFormData,
                    success: function (data) {

                        //displays preview of the post

                    },

                    error: function (textStatus) {

                        //displays errors


                    }
                });

            });
        }else{

                //displays an error re the image is not present.
                // Now this is not optimal as the image is not the only required field

        }
    });
});

This is the promise function that prepares the manipulated image, it calls some other functions for the real processing:

function processImage(file) {

    return new Promise(function (resolve, reject) {

        if (file.type.match('image.*') && file.length != 0) {

            var reader = new FileReader();

            reader.readAsDataURL(file);

            reader.onloadend = function () {

                var base64img = this.result;

                var exif = EXIF.readFromBinaryFile(base64ToArrayBuffer(this.result));
                var srcOrientation = exif.Orientation;

                resetOrientationResizeCompress(base64img, srcOrientation).then((img)=> {

                    dataURItoBlob(img).then((ia)=> {

                        resolve([img, ia]);

                    });

                });
            };
        }else{

            //don't really know what to do here really, or if this is the way

            reject();

        }
    });
}
Share Improve this question edited Jun 1, 2017 at 17:44 Chriz74 asked Jun 1, 2017 at 17:33 Chriz74Chriz74 1,4803 gold badges24 silver badges48 bronze badges 6
  • 1 Well yes, you don't handle any rejections of that processImage(…).then(…) promise? Just append a .catch(console.error) to that chain. – Bergi Commented Jun 1, 2017 at 21:29
  • 1 Avoid the Promise constructor antipattern! Do resolve(this.result) only, and do all the other stuff in a then handler. – Bergi Commented Jun 1, 2017 at 21:30
  • Ok, appending the .catch(console.error) to the chain made the uncaught error disappear. The question is, what do I do with that console.error object? And also where is the anti pattern in the code above? – Chriz74 Commented Jun 5, 2017 at 13:09
  • Well, what do you want to do with errors? – Bergi Commented Jun 5, 2017 at 13:13
  • Well I am already showing input errors in error: function (textStatus) , the object that I get with the .catch(console.error) contains the same data. – Chriz74 Commented Jun 5, 2017 at 13:14
 |  Show 1 more ment

1 Answer 1

Reset to default 4

It is telling you that you are not catching the error rejection, append .catch to the processImage(files[0]) promise.

本文标签: javascriptHow to deal in uncaught in promise errorStack Overflow