Dropzone remove on click fires the xhr request multiple times

75 Views Asked by At

I'm working with laravel and added in an image uploader using Dropzonejs 5x and ran into a really odd issue where when there are more than one image uploaded, if I click remove on one, it fires off the xhr request for the image I click removed on, but it fires the request a number of times equal to how many images I have total.

I'm pulling in dropzone via cdn and am using dropzone declaratively according to the docos.

Here is the blade file

<div class="panel panel-default" id="dashboard-recent">
    <div class="panel-heading" >
            <span class="panel-title">
                <i class="panel-title-icon fa fa-picture-o hidden-xs"></i>&nbsp;
            </span>
            <form action="/requests/{{$request->id}}/photo-upload" class="dropzone" id="request-photo-upload">
                @csrf
                @method('POST')
            </form>
    </div>
</div>

@section('head-styles')
<link rel="stylesheet" href="https://unpkg.com/dropzone@5/dist/min/dropzone.min.css" type="text/css" />
<style>

.dropzone{
    .dz-preview{
        .dz-image{
            img{
                height: 100%;
                width:100%;
                object-fit: cover;
            }
        }
    }
}
</style>
@stop

@section('head-scripts')
<script src="https://unpkg.com/dropzone@5/dist/min/dropzone.min.js"></script>
<script src="/js/requests-dropzone.js" id="requests-dropzone" request="{{$request->id}}"></script>
@stop

Here is the javascript to handle Dropzone

@section('javascripts')
<script>
    let endpoint = "/requests/{{$request->id}}/photo-upload";

    Dropzone.options.requestPhotoUpload = {
        paramName: "file",
        maxFiles: 5,
        maxFilesize: 4, // MB
        uploadMultiple: true,
        parallelUploads: 1,
        addRemoveLinks: true,
        dictRemoveFile: "Delete",
        init: function() {
            this.on("success", function(file, serverResponse) {
                var fileuploded = file.previewElement.querySelector("[data-dz-name]");
                fileuploded.innerHTML = serverResponse.newfilename;
            });
            this.on("addedfile", function(file) {
                file.previewElement.querySelector('[data-dz-name]').textContent = file.upload.filename;
            });
            this.on("complete", function(file) {
                $(".dz-remove").html("<div><span class='fa fa-trash text-danger' style='font-size: 1.5em'></span></div>").on('click', function(e) {
                    e.preventDefault();
                    e.stopPropagation();
                    let imageId = $(this).parent().find(".dz-filename > span").text();
                    let uri = endpoint + `/${imageId}`;
                    axios.delete(uri)
                        .then(response => {
                            console.log(`Deleted photo with ID ${imageId}`);
                        })
                        .catch(error => {
                            console.error(error);
                        });
                });
            });

            let thisDropzone = this;
            axios.get(endpoint)
                .then(response => {
                    this.data = response.data;
                    this.data.forEach(function(item) {
                        let mockFile = {"name": item.name, "request": item.request, "size": item.size, "path": item.path};
                        thisDropzone.options.addedfile.call(thisDropzone, mockFile);
                        thisDropzone.options.thumbnail.call(thisDropzone, mockFile, mockFile.path);
                        thisDropzone.emit("complete", mockFile);
                    });
                })
                .catch(error => {
                    console.error(`Error fetching request ${this.request.id}`, error)
                })
        }
    };

</script>
@stop

I can see in the network tab when I click the trash can on a single image that it calls the correct endpoint with the correct method (delete) but it does it four times (because I have four images total). I'm attaching two screenshots showing first four images, then only three and the four total xhr calls, additionally I do see three console logs of image deletion so the click event seems to be firing multiple times off a single click.

Four Images no network calls Removed one and four xhr calls

I'm sure it's something I'm not doing correctly in the dz-remove onclick but I cannot for the life of me figure out what it is.

1

There are 1 best solutions below

0
Jchieppa On BEST ANSWER

In case anyone else runs into something similar I solved this by moving the ajax call into it's own event handle, which I able to find looking at the actual source code in options.js

this.on("removedfile", function(file){
            filename = file.name.split('.')
            let uri = endpoint + `/${filename[0]}`;
            console.log(uri);
            axios.delete(uri)
                .then(response => {
                    console.log(`Deleted photo with ID ${file.name}`);
                })
                .catch(error => {
                    console.error(error);
                });
       });