19
Views
8
Comments
[ReactFilePondUpload] Issue with FilePond process callback in list scenarios
reactfilepondupload
Reactive icon
Forge asset by Stuart Harris
Application Type
Reactive
Service Studio Version
11.55.20 (Build 64140)
Platform Version
11.33.1 (Build 44835)

Hello,

I'm running into an issue with the ReactFilePondUpload component (O11) when it's used within a list of records (e.g., works, users, tasks, etc.). Each item in the list has its own instance of FilePond to allow file uploads, but I’m noticing an unexpected behavior.

When uploading a file on the first item in the list, the following happens:

  • The addfilestart event triggers the sendStartCallback, but it receives the last record in the list, as if the plugin instance had been overwritten.

  • The processfile event correctly receives the right ID.

This suggests that the pluginId is being shared across all instances, which isn’t the intended behavior. 


Expected Behavior:

Each FilePond instance should have its own independent context and callbacks, even when they are part of a list on the same page. This way, interactions with one instance don’t affect others.


The Issue: 
Looking into the JavaScript code, I noticed the following logic in FilePondUploadFactoryFn:

if (!pluginId) {

    pluginId = "filePondUpload" + nextIdNumber++;

}

Since pluginId is optional, and the fallback is an incremented value, I’m wondering if plugin instances could be unintentionally overlapping. Later, when FilePond calls: 

var plugin = FilePondUploadFactory.getPlugin(fieldName);

…it seems that fieldName may not be unique in this context, possibly causing it to return the wrong plugin (typically the last one created). 


Has anyone encountered this issue before? Is there a recommended way to use this component safely within a ListRecords structure? I'm especially interested in how to ensure each instance retains its context correctly.

If possible, could you share an example of how this component should be used with ListRecords? Seeing a working implementation in that context would be extremely helpful.

Thanks in advance for your time and support! 😊

2024-11-07 03-28-42
Stuart Harris
Champion

Hi Sandra,

Thank you for your question and detailed investigation.

This is not a scenario I have tested using multiple instances of the upload control in a list.

When I have multiple instances on a page, I usually specify the WidgetId parameter.

A few questions for you to help us all diagnose.

  • Which block are you using; UploadBlock or AutoUploadBlock?
  • Are you specifying the WidgetId in each instance?
  • Can you clarify a little further this "but it receives the last record in the list". What list do you mean? Also, how do you know it receives the last record in the list (I'm assuming debugging in the browser and you've checked the parameter and the list of plugin values, but I just want to be sure).
  • Can I confirm that the UploadStarted event is always being triggered only for the last upload block rendered, regardless of the instance which triggered the event? or it is something else?
  • And for working out priority: Is this causing a development blockage for you? Do you have a deadline for this? What is the impact if this is not resolved?

Thanks and looking forward to hearing from you.

Kind regards,

Stuart

2020-02-11 23-17-13
Sandra Ferreira

Hi Stuart,

First of all, thank you so much for your quick reply and for taking the time to look into my question — I really appreciate it.

Apologies for the delay in getting back to you. I took a bit of extra time to prepare and attach a sample .osp solution that reproduces the issue, so it’s easier to follow along and understand the scenario.

Due to the 4MB attachment limit, here's a link to the .osp file via Google Drive: FilepondInsideTable.osp

Also, just to correct something I mentioned earlier — I mistakenly said "ListRecords" when I actually meant "TableRecords".



📎 Attachement

The attached .osp simulates the scenario we’re working on. It includes a table of employees (MaxRecords = 5), and each row contains an UploadBlock (display-none) plus a custom icon that we use to control the upload UI.

We’re not using FilePond's native file selector directly in the UI. Instead:

  • Red icon = requires file

  • Spinner = uploading

  • Green icon = file uploaded

When the red icon is clicked, a JavaScript function is triggered that: 

  1. Receives the WidgetId from the UploadBlock.

  2. Uses querySelector('input[type="file"]') (scoped within the container of that WidgetId) to simulate a click.

  3. This opens the browser’s file selection popup.

The hidden UploadBlock has its WidgetId explicitly set (using UploadBlock.Id), and it is also passed to the script. So far, all WidgetIds and container IDs are unique, and the file input selector is working correctly (verified via DOM inspection — only one such input per widget). 


🧪 Observed Behavior

After selecting a file:

  • UploadFileChunksStart is triggered, but receives the last record in the table (i.e., the UploadBlock that was initialized last in OnReady).

  • UploadFileChunk follows with the same (incorrect) WidgetId.

  • However, NotifyUploaded does receive the correct WidgetId — the one that triggered the upload.

In the UI, you’ll see that IsUploading is incorrectly set to true in the last row — even though the file was selected in the first row. This causes visual inconsistency and potential functional misalignment.

I verified this by:

  • Debugging your FilePondUploadConfigureJS actions (UploadFileChunksStart, UploadFileChunk, NotifyUploaded)

  • Inspecting DOM manually

  • Displaying variables in the UI (old-school debugging 😄)


🔍 Investigation Points

Looking into the component FilePondUploadFactoryFn, I found this:

if (!pluginId) {

    pluginId = "filePondUpload" + nextIdNumber++;

}

Since pluginId is optional and auto-generated if not set, my hypothesis is:

  • The plugin instance is stored globally using pluginId, and reused by default.

  • In a TableRecord, multiple UploadBlocks are rendered — each one calling OnReady and initializing FilePondUploadFactory.create(...).

  • The last initialized plugin overwrites the previous one, which means when FilePond triggers events (like addfilestart → sendStartCallback), it uses the last available plugin, regardless of which input was actually used.

Supporting this theory:

  • When the browser file dialog opens, the file input is correctly scoped.

  • But once a file is selected, the upload events bind to the last UploadBlock in the DOM.

  • The input element has a name=WidgetId, but when triggered via our JS, that name seems to disappear or not be set correctly — I wasn’t able to confirm if that’s normal or a clue.


📌 Your Questions

Which block are you using; UploadBlock or AutoUploadBlock? UploadBlock

Are you specifying the WidgetId in each instance? Yes. UploadBlock.Id is passed as WidgetId and used in the JS to target the input.

Can you clarify a little further this "but it receives the last record in the list". What list do you mean? My mistake — it's a TableRecord. When uploading from the first row, the JS actions (UploadFileChunksStart, UploadFileChunk) are triggered with the last UploadBlock’s WidgetId.

Also, how do you know it receives the last record in the list? I checked the plugin IDs in the JS, verified UI behavior, and printed debug data directly in the UI (see example).

Can I confirm that the UploadStarted event is always being triggered only for the last upload block rendered, regardless of the instance which triggered the event? Yes, from what I can tell, the FilePond plugin is reinitialized for every UploadBlock, but only the last one ends up being used by FilePond events — even if the file input used was from an earlier block.

And for working out priority: Is this causing a development blockage for you? Do you have a deadline for this? What is the impact if this is not resolved? It was a blocker, but I’ve since changed our approach to use the component more directly in the UI, avoiding the dummy click. That said, I would still like to understand how to safely use multiple UploadBlocks in repeatable patterns like TableRecords — especially if what I described is expected or not.


Thanks again for your support and for maintaining a great component. Looking forward to your insight!

Kind regards,
Sandra Ferreira  

2024-11-07 03-28-42
Stuart Harris
Champion

Hi Sandra,

Thank you again for your awesome and detailed responses, and for providing a sample app.

For this issue, I imagine it will be a similar issue for tables and lists.

There is probably a subtle error in my integration code, but I wonder if when passing the block action to be called back, whether it gets overwritten and always calls the last one.

I will have a look this weekend. I'm glad its no longer a blocker for you, because that takes the pressure off (and it's Mothers Day in Australia this weekend..).

If you don't hear anything for a while, please feel free to post "Hey Stuart how are you going with it?", it may be that I'm slacking off watching Netflix or something..

Kind regards,

Stuart

2024-11-07 03-28-42
Stuart Harris
Champion

And kudos for the old-school debugging :)

2020-02-11 23-17-13
Sandra Ferreira

Hi Stuart,

Thank you so much once again — no need to worry at all! I really appreciate your help, and I’ll make sure to reach out if I get stuck again.

Enjoy Mother’s Day in Australia — hope you have a lovely and relaxing weekend! :)

Kind regard,

Sandra

2024-11-07 03-28-42
Stuart Harris
Champion

Hi Sandra,

I think I've found your problem.

I couldn't replicate the issue, so I checked which version you were using, and its not the latest.

So please install the latest version, and that should solve your problem.

I notice you are using an older version of OutSystems UI, so you might want to update that as well. Although that will require testing and redeploy of all your applications. I guess thats why you haven't updated the ReactFilePondUpload component. But if you force install and just update dependencies you should be fine. It doesn't depend on much that will change.

Also, there are some minor changes to the module, so these will be overridden when you install the latest. The changes involve exposing the action to retrieve a single file instead of multiple files. However, you can use the action to retrieve multiple files and just select the first one when you setting MaxFiles = 1.

I hope this helps!

Kind regards,

Stuart

PS I knew there was another question I should have asked!

2020-02-11 23-17-13
Sandra Ferreira

Hi Stuart,

Oh my god — I completely overlooked the fact that we’re using a customized version of the component, which explains why we haven’t been able to update it easily. That’s on me!

Regarding OutSystems UI, we’re actually using version 2.22.0, which I believe is the latest stable version. So if the .osp I sent you came with an older version, that must have slipped through when I was preparing the sample — my apologies for that as well.

I really appreciate your input, and you’re absolutely right — updating FilePondUpload is something that requires a bit of finesse on our side due to some internal adjustments we’ve made. But I’ll try to schedule that for next week and will definitely share feedback once it’s done.

Thanks again for pointing me in the right direction (and for reading my wall of text with such patience!).

Wishing you a great continuation of Mother’s Day weekend :)

Kind regard,
Sandra Ferreira

2024-11-07 03-28-42
Stuart Harris
Champion

Hi Sandra,

No worries at all, I should have remembered I fixed that issue.

On OutSystems UI, maybe I need to update my version of OutSystems UI, it was just different and I assumed it meant you were using an older version, but its probably me. I usually try and keep the components on a slightly older version so people don't have problems updating.

All the best, and please let me know if you have any further issues.

Kind regards,

Stuart

Community GuidelinesBe kind and respectful, give credit to the original source of content, and search for duplicates before posting.