Sending additional data with programatically created Dropzone using the sending event
Asked Answered
O

4

7

I have the following (simplified for example) angular directive which creates a dropzone

directives.directive('dropzone', ['dropZoneFactory', function(dropZoneFactory){
    'use strict';
    return {
        restrict: 'C',
        link : function(scope, element, attrs){

            new Dropzone('#'+attrs.id, {url: attrs.url});

            var myDropZone = Dropzone.forElement('#'+attrs.id);


            myDropZone.on('sending', function(file, xhr, formData){
                //this gets triggered
                console.log('sending');
                formData.userName='bob';
            });
        }
    }
}]);

As you can see the the sending event handler I'm trying to send the username ("bob") along with the uploaded file. However, I can't seem to retrieve it in my route middleware as req.params comes back as an empty array (I've also tried req.body).

My node route

    {
    path: '/uploads',
    httpMethod: 'POST',
    middleware: [express.bodyParser({ keepExtensions: true, uploadDir: 'uploads'}),function(request,response){
        // comes back as []
        console.log(request.params);

        //this sees the files fine
        console.log(request.files);

        response.end("upload complete");
    }]
}

Here is what the docs say on the sending event

Called just before each file is sent. Gets the xhr object and the formData objects as second and third parameters, so you can modify them (for example to add a CSRF token) or add additional data.

EDIT

I dropped the programmatic approach for now. I have two forms submitting to the same endpoint, a regular one with just post and a dropzone one. Both work, so I don't think it's an issue with the endpoint rather with how I handle the 'sending' event.

//Receives the POST var just fine
form(action="http://127.0.0.1:3000/uploads", method="post", id="mydz")
    input(type="hidden", name="additionaldata", value="1")
    input(type="submit")

//With this one I can get the POST var
form(action="http://127.0.0.1:3000/uploads", method="post", id="mydz2", class="dropzone")
    input(type="hidden", name="additionaldata", value="1")
Once answered 21/2, 2014 at 18:25 Comment(6)
Hi Nicolas. I suspect it's related to the way you're configuring Express. I've never seen such configuration. Would you mind giving much details on how you create and configure your routes ? Generally, we configure routes this wayOriya
I doubt it. I've sent a regular html form to the same endpoint and it all works smoothly so I think the problem is how I send the data through Dropzone. Do you have an example where sending the data works? I've also tried the way they have in their FAQ (dropzone in the html as oppsoed to creating progamatically) but it also doesn't work.Once
How did you send your userName in your html form ? as query or form parameter ?Oriya
@Oriya see edit, it;'s a form parameters send through postOnce
Actually It's working now with the second form. However, if I try to do it programmatically (myDropZone.on('sending', ...), it doesn't work. Any clue?Once
I could modify my directive to create a form like in my second example, but it sucks that you can't do it programmatically.Once
O
20

OK, I've actually figured it out, thanks to Using Dropzone.js to upload after new user creation, send headers

The sending event:

        myDropZone.on('sending', function(file, xhr, formData){
            formData.append('userName', 'bob');
        });

As opposed to formData.userName = 'bob' which doesn't work for some reason.

Once answered 21/2, 2014 at 20:31 Comment(0)
E
1

I would like to add to NicolasMoise's answer. As a beginner in webdev I got stuck on how to obtain an instance of Dropzone. I wanted to retrieve an instance of Dropzone that had been generated by the autodiscovery feature. But it turns out that the easiest way to do this is to manually add a Dropzone instance after first telling Dropzone not to auto-discover.

<input id="pathInput"/>
<div id="uploadForm" class="dropzone"/> 
<script>
  $(document).ready(function(){
    Dropzone.autoDiscover = false;
    var dZone = new Dropzone("div#uploadForm", {url: "/api/uploads"});
    dZone.on("sending", function(file, xhr, data){
      data.append("uploadFolder", $("#pathInput")[0].value);
    });
  });
</script>

Serverside the data will be in request.body.uploadFolder

Emunctory answered 18/5, 2015 at 13:45 Comment(0)
A
1

Nicolas answer is one possible solution to the problem. It is especially useful if you need to alter the file object prior to sending.

An alternative is to use the params option:

var myDropzone = new Dropzone("div#myId", 
                              { url: "/file/post", params: { 'param_1': 1 }});

cf. the documention

Alarick answered 11/3, 2016 at 21:5 Comment(0)
M
0

For those that are using thatisuday/ng-dropzone the callback methods are done as such:

    <ng-dropzone class="dropzone" options="dzOptions" callbacks="dzCallbacks" methods="dzMethods"></ng-dropzone>

In a controller:

    $scope.dzCallbacks = {
        sending: function(file, xhr, form) {
            console.log('custom sending', arguments);
            form.append('a', 'b');
        }
    };
Missymist answered 1/3, 2017 at 6:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.