Search code examples
ajaxform-data

uploading an image immediately after selection using ajax without onclick event


I am trying to upload an image in laravel using ajax as bellow

    $(document).ready(function () {
        bsCustomFileInput.init();
        $('#exampleInputFile').on('change', function(){
            var file = this.files[0];
            var fileType = file["type"];
            var validImageTypes = ["image/gif", "image/jpeg", "image/png"];
            if ($.inArray(fileType, validImageTypes) < 0) {
                // invalid file type code goes here.
                alert('Please select a valid image in the following formats .gif, .jpeg, .png');
            }else{
                //get the image and place it in a variable
                $.ajaxSetup({
                    headers: {
                        '_token' : $('input[name=_token]').val()
                    }
                });
                var formData = new FormData(document.getElementById("#upload-image-form"));
                alert("Created FormData, " + [...formData.keys()].length + " keys in data");
                $('#image-input-error').text('');
                $.ajax({
                    type:'POST',
                    url: `/property/images/add`,
                    data: formData,
                    contentType: false,
                    processData: false,
                    success: function(response) {
                        if (response) {
                        $('#exampleInputFile').reset();
                        $('#images').append("<img class='img-responsive' src='uploads/property/small/"+
                        response.path +"'/>");
                        alert('Image has been uploaded successfully');
                        }
                    },
                    error: function(response){
                        console.log(response);
                            $('#image-input-error').text(response.responseJSON.errors);
                    }
                });
            }
        });
    });

My problem is that after selection I get the following error

    Uncaught TypeError: Failed to construct 'FormData': parameter 1 is not of type 'HTMLFormElement'.
at HTMLInputElement.<anonymous> (add:234)
at HTMLInputElement.dispatch (jquery.min.js:2)
at HTMLInputElement.v.handle (jquery.min.js:2)

The line throwing the error is the one that instantiates the FormData. What could I be doing wrong or rather how can I get the image uploaded without click event?


Solution

  • After numerous attempts and reading, I ended up with this code

        <script type="text/javascript">
        $(document).ready(function () {
            bsCustomFileInput.init();
            $.ajaxSetup({
                headers: {'X-CSRF-TOKEN': $('input[name=_token]').val()}
            });
    
            $('#images').change(function () {
                event.preventDefault();
                let image_upload = new FormData();
                let TotalImages = $('#images')[0].files.length;  //Total Images
                let images = $('#images')[0];  
                let p_id = $('input[name=p_id]').val();
    
                for (let i = 0; i < TotalImages; i++) {
                    image_upload.append('images[]', images.files[i]);
                }
                image_upload.append('TotalImages', TotalImages);
                image_upload.append('p_id', p_id);
    
                $.ajax({
                    method: 'POST',
                    url: '{{ route('image.add') }}',
                    data: image_upload,
                    contentType: false,
                    processData: false,
                    success: function (images) {
                        Swal.fire(
                        'Success!',
                        'Images uploaded successfully',
                        'success'
                        );
                        $('#images').reset();
    
                    },
                    error: function () {
                        Swal.fire(
                        'Failed!',
                        'An error occured please try again',
                        'error'
                        );
                        $('#images').reset();
                    }
                });
    
            });
        });
    </script>
    

    It does work and eliminates the failing point and also updates on the one previously used