vue-filepond icon indicating copy to clipboard operation
vue-filepond copied to clipboard

Binding to "files" variable doesn't updates after file upload"

Open novikov-alexander-zz opened this issue 6 years ago • 18 comments

I've created a component with this bindings:

<file-pond name="test"
                   ref="pond"
                   label-idle="Перетащите сюда файлы..."
                   max-files="4"
                   allow-multiple="true"
                   accepted-file-types="csv, shx, shp, dbf"
                   server="/Loader/Upload"
                   v-bind:files="myFiles"
                   v-on:init="handleFilePondInit" />
        <div v-for="(item, index)  in myFiles">
            <input asp-for="filenames[i]" v-bind="item" type="hidden" />
        </div>

But v-for doesn't work because "myfiles" doesn't update

novikov-alexander-zz avatar May 23 '18 16:05 novikov-alexander-zz

Hi @novikov-alexander the files binding is currently only for programmatically adding initial files, or updating the current file set, it doesn't (currently) reflect the state of loaded (dropped) files.

I'll see if I can add this in a future release ( pull requests are also welcome ) as it would be a very useful feature to have.

rikschennink avatar May 23 '18 18:05 rikschennink

Hi @rikschennink I made this workaround for the problem:

export default Vue.extend({
    template: "#dataloader-template",
    data() {
        return {
            myFiles: [],
            uploadedFiles: []
        };
    },
    methods: {
        handleFilePondInit: function () {
            console.log('FilePond has initialized');
        },
        handleFilePondProcessfile: function (error, file) {
            console.log("FilePond succesfully processed file " + file);
            this.uploadedFiles.push(file.filename);
            this.$nextTick();
        },
        handleFilePondRemovefile: function (file) {
            console.log("FilePond deleted file " + file.filename);
            var index = this.myFiles.indexOf(file.filename);
            if (index > -1) {
                this.uploadedFiles.splice(index, 1);
                this.$nextTick();
            }
        }
    }
});

I haven't got enough work time on weekdays for adding this functionallity to vue-filepond but I think I can make it on the weekend :-)

novikov-alexander-zz avatar May 29 '18 13:05 novikov-alexander-zz

@novikov-alexander Awesome! I'll definitely test this later this week.

rikschennink avatar May 29 '18 13:05 rikschennink

That will be an awesome functionality, in my case I don't want to make automatic updates to the server and having a lot of refs can be a hassle. This will simplify getting the files 💯

larizzatg avatar May 30 '18 15:05 larizzatg

Hi. Sorry to "reanimate" this issue, but has any of you managed to implement this in the current build?

oiagorodrigues avatar Mar 10 '19 01:03 oiagorodrigues

@oiagorodrigues I use a similar solution as @novikov-alexander https://github.com/pqina/vue-filepond/issues/18#issuecomment-392769848 (i don't know why he uses this.nextTick())

Wifsimster avatar Apr 03 '19 12:04 Wifsimster

I apologize in advance for the silly question, but what events are firing the handleFilePondProcessfile and handleFilePondRemovefile from @novikov-alexander-zz example? The html for the filepond component is omitted and nothing I've tried has worked.

jaymefrantz avatar Apr 03 '21 03:04 jaymefrantz

@jaymefrantz You probably already figured it out, but you need to use something like this:

<file-pond
  @processfile="handleFilePondProcessfile"
  @removefile="handleFilePondRemovefile"
  ...
></file-pond>

See the list of available callbacks, but you have to remove the on prefix.

I'm not sure if the removefile callback is meant to be used in the example by @novikov-alexander-zz or processfilerevert, since the function signature for removefile needs to have an error as first argument, not a file:

handleFilePondRemovefile: function (error, file) {

avioli avatar Jun 29 '21 00:06 avioli

Now we can use the Added v-model support

scil avatar May 30 '22 08:05 scil

@scil Do you have any example on how that works ? I still can't get list of uploaded files, not with :files and not with v-model I'm using Vue 3 btw

HassanZahirnia avatar Jun 25 '22 17:06 HassanZahirnia

@scil Do you have any example on how that works ? I still can't get list of uploaded files, not with :files and not with v-model I'm using Vue 3 btw

i use vue 2


<template>
    <file-pond
      name="file-uploader"
      ref="pond"
      credits="false"
      :label-idle="labelIdle"
      :allow-multiple="false"
      accepted-file-types="image/*"
      :server="server"
      :files="setFiles"
      v-model="currentFiles"
      :dropOnElement="!dropOnPage"
      :dropOnPage="dropOnPage"
      @init="handleFilePondInit"
    />
<!--      @processfile="onProcessfile"-->
<!--      @removefile="onRemovefile"-->
<!--      @addfile="onAddfile"-->
</template>

related var:

  data: function () {
    return {
      currentFiles:null,  // I think it is same as this.$refs.pond.getFiles()
       ....
    };
  },

scil avatar Jun 26 '22 00:06 scil

@scil Thanks for sharing. Unfortunately I could not get it working with Vue 3. The usage with the Vue adapter is confusing as they're not many examples around.

For now I just went with pure Javascript. It's easier this way since there is 1 less layer to deal with and instead of focusing on how the Vue adapter works I can focus on the library itself and get my app built quickly 👍

HassanZahirnia avatar Jun 26 '22 09:06 HassanZahirnia

@scil Thanks for sharing. Unfortunately I could not get it working with Vue 3. The usage with the Vue adapter is confusing as For now I just went with pure Javascript. It's easier this way since there is 1 less layer to deal with and instead of focusing on how the Vue adapter works I can focus on the library itself and get my app built quickly 👍

I agree with you. At First i used pue js, but later I went to vue-filepond, because I'am working with a large vue app where filepond is just a part.

maybe you can just test v-model="currentFiles" to get the current files, while :files="setFiles" is to set the initial files.

scil avatar Jun 26 '22 10:06 scil

@novikov-alexander-zz how can I achieve this with javascript?

shivam464 avatar Nov 02 '22 17:11 shivam464

Anyone else managed to get v-model working with vue3?

aonghas avatar Aug 15 '23 21:08 aonghas

In case anyone needs to know how it works in vue3:

<template>
 <file-pond   
        name="photoupload"
        ref="pond"
        @updatefiles="onUpdateFiles"
      />
</template>
      
<script setup>
      const pondFiles = ref([]);

      function onUpdateFiles(files) {
        pondFiles.value = files;
      }

</script>

aonghas avatar Aug 15 '23 22:08 aonghas

@aonghas The problem with your solution is that updateFiles seems to fire (and emit) files as soon as they are added to the component, before they finish uploading (processfile event). So if they fail they are still emitted as added. The same is true of the new Input event. This is not acceptable behaviour for my needs.

So I use processfile and removefile events to emit "update:modelValue" with props.modelValue bound to :files, but this seems to come with it's own problem. As soon as I emit a "update:modelValue" from the processfile event handler, this updates the parent v-model which in return updates my :files bind, which then fires a removeFile event (since :files seems to clear the internal store) and this ends up clearing the whole component...

@rikschennink Either updating :files should not emit removefile (or at least not fire for files that already exist in the state) or :files needs to become fully reactive (i.e. v-model).

If any of you have any suggestions how to bridge this gap now, I will be extremely thankful (I really don't wish to switch upload components because of this)

rootwalla avatar Mar 21 '24 08:03 rootwalla

@rootwalla I'm addressing this in FilePond v5 where files always reflects the current state.

rikschennink avatar Mar 25 '24 15:03 rikschennink