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

serverConfig load: works locally, but not when the build is pushed to it's AWS S3 Host.

Open michaelcuneo opened this issue 3 years ago ā€¢ 17 comments

Describe the bug

A clear and concise description of what the bug is.

Not sure if this is a bug, or just a usage problem.

I have quite an editor with a react FilePond component inside for uploading images to an AWS S3 stack. Adding, and Deleting from this S3 Stack using the FilePond works fine...

Editing works fine but only locally.

If I want to edit my file, I use this following setup.

const serverConfig = {
    load: (source, load) => {
      const myRequest = new Request(source);

      fetch(myRequest).then(response => {
        response.blob().then(myBlob => load(myBlob));
      });
    },
  };
<FilePond
   id="file"
   name="file"
   key="file"
   ref={filePondFeature}
   files={values.file}
   instantUpload={false}
   server={serverConfig}
   upload="false"
   onClick={() => setFieldTouched('file', true)}
   onChange={() => setFieldTouched('file', true)}
   oninit={() => setFieldValue('file', file.file)}
   onupdatefiles={fileItems => {
      const thisFiles = fileItems.map(
         thisFile => thisFile.file,
      );
      setFieldValue('file', thisFiles);
      fileItems.map(thisFile =>
         handleAddFeatureFile(thisFile.file),
      );
    }}
/>

Logs

Running the project locally while in development, I get images loaded externally into the FilePond component perfectly fine.

As you can see the Logs show a blob: with data.

image_load image_load_2

The exact same app, built and hosted online on an AWS S3 Stack doesn't give me any blob at all.

If I log the source locally, I get an appropriate response with an amazon S3 endpoint and URL and credentials for the image I need to load. then I log the blog object and I get an appropriate blob response.

storage_master

I can't get any kind of log from the remotely hosted side because it's obviously not allowing console.log's or alerts. Not sure how to troubleshoot the other end.

michaelcuneo avatar Nov 16 '20 04:11 michaelcuneo

Further to my issue, I've hard coded some variables to be displayed above the FilePond window so that I can screenshot the local running version, and the build hosted from S3.

These are my results. The serverConfig is being ignored running from an S3 it seems... it's really odd... both local and remote copies are identical code.

Working Local Build WorkingLocal

Failed Build running on S3 Failed_External

michaelcuneo avatar Nov 16 '20 05:11 michaelcuneo

Iā€™d look at the developer tools network tab and console to see if there are any errors and/or if the requests both look the same.

rikschennink avatar Nov 16 '20 06:11 rikschennink

There are no requests at all. If I throw an alert/log, or even set a variable inside server load, to see if it's being called... it isn't.

michaelcuneo avatar Nov 16 '20 06:11 michaelcuneo

Hitting the edit page locally, I instantly get 5 x 200's and some logs.

Local_Req

Hitting the edit page remotely on the S3 Stack, I get the single GraphQL request, and no other requests or logs.

GraphQL_Req

Same code, same page, same post to edit in both

michaelcuneo avatar Nov 16 '20 07:11 michaelcuneo

You can see the URL in the console if you want to have a look... https://admin.soci.org.au/

michaelcuneo avatar Nov 16 '20 07:11 michaelcuneo

I'm sorry I don't know why this is happening but I suspect it's not related to FilePond.

rikschennink avatar Nov 17 '20 10:11 rikschennink

It looks like it might be a condition of how and when to render things and when to not render things, because of my complex usage structure. I have the FilePond components wrapped in Formik to validate. I stripped all Formik validation areas from the FilePond component and gave it raw files values, and actually got it to function locally and remotely.

But, there's now an issue with the timing for huge amounts of images, I don't load FilePond until the entire initial files variable is filled with all files to be loaded into FilePond, yet I often get

12.3afc4c7e99aef37ad7d5.chunk.js:1 GET https://admin.soci.org.au/[object%20Object] 404
12.3afc4c7e99aef37ad7d5.chunk.js:1 Uncaught (in promise) TypeError: e.split is not a function

But they are not objects, I can see them loading and their real filenames, they just don't get that far... this happens both locally and remotely.

When I actually get a debug locally, I get

Uncaught (in promise) TypeError: url.split is not a function
    at getFilenameFromURL (filepond.js?c062:4291)
    at eval (filepond.js?c062:4636)

direct_site

And this is my files object after this request.

Request

This request is actually meant to be one single image. Yet it's the initial source provided to load, then the response twice, then the converted blob twice. It's as if the load doesn't know how to stop. Or what file to use to put into files. The relationship between server: load: and onupdatefiles seems to be lacking.

michaelcuneo avatar Nov 17 '20 22:11 michaelcuneo

This is so project specific. Please create a concise test case on codesandbox.io happy to take a look but I'm afraid I can't help out further.

rikschennink avatar Nov 18 '20 10:11 rikschennink

I am in the middle of creating one, but this never works out well for me, due to the fact that sandbox projects don't ever end up identical to my actual problem, and usually work fine, but in this case it is actually broken. I can't even get it to run without infinite loop.

https://codesandbox.io/s/filepond-recursion-545po?file=/src/App.js

michaelcuneo avatar Nov 23 '20 00:11 michaelcuneo

From what I can see... onupdatefiles triggers for every single step of the server load process... so grabbing the file, triggers an onupdatefiles, with a failure receiving an [object object], then the next step triggers it again for the actual file, then the next step converting it to a blob triggers it again. So I end up with sometimes 6 files when I'm only loading 2... then of course because it's adding the files on load, it's updating them and it just loops. I have managed to get it to stop looping by switching onupdatefiles off, but then I never get new files in my file list, which is useless.

michaelcuneo avatar Nov 23 '20 00:11 michaelcuneo

This will probably cause issues:

{initialFiles.map((thisFile) => (
          <File key={thisFile} src={thisFile} options={"local"} />
))}

rikschennink avatar Nov 24 '20 15:11 rikschennink

All methods of initial files, then adding more causes issues. None of them work effectively. It seems as though this is impossible.

Sent from my iPhone

On 25 Nov 2020, at 2:10 am, Rik [email protected] wrote:

ļ»æ This will probably cause issues:

{initialFiles.map((thisFile) => ( <File key={thisFile} src={thisFile} options={"local"} /> ))} ā€” You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

michaelcuneo avatar Nov 24 '20 18:11 michaelcuneo

I have modified this sandbox about 8 times in the last 24 hours to include every single method of providing initial files, then adding more files afterwards... all break, and all do not function. Is there any documentation anywhere that provides a valid method of performing this in React-Filepond, I'm in a mission critical project that was due months ago.

I can set initialFiles, I can have them load up perfectly fine... adding more though, never works correctly. I get an Infinite Loop so me adding the <File /> component was another one of my tests to determine which one would actually perform what I need.

I've tried using server: load. I've tried this in a component scenario, I've tried this in a hooks scenario, i've tried providing initial files as an array of objects in the following format

{
  source: file,   
    options: {
      'local',
    }
}

I can get initial files in this manner... while setting server to the following

        server={{
          load: (source, load, error, progress, abort, headers) => {
            var myRequest = new Request(source);
            fetch(myRequest).then(function(response) {
              response.blob().then(function(myBlob) {
                load(myBlob);
              });
            });
          }
        }}

This is the closest I have got to it functioning. But when I load it up I get an infinite loop.

It's not even a complex use case, it's what anyone would need to do with this.

michaelcuneo avatar Nov 24 '20 19:11 michaelcuneo

I'm in a mission critical project that was due months ago.

Don't move your development pressure on to me please.

rikschennink avatar Nov 25 '20 08:11 rikschennink

I've managed to get this working, in an extremely unconventional manner.

Adding files to filepond initially, then adding and / or removing files, 100% fails every single time, unless you add the function onupdatefiles = {} to the component, but leave it entirely blank. Using it to actually perform any updates to the local files, breaks the entire component, which is rather unusual. I've placed a function into the component, which does exactly nothing... but it does fix the component... maybe it should be changed to a bool, because obviously everyone wants to update their files.

Adding the files.

  const [files, setFiles] = useState({ files: [] });

  useEffect(() => {
      // Grab the Gallery Images
      if (project.gallery !== null) {
        project.gallery.images.items.map(item => [
          Storage.get(item.key)
            .then(data => handleAddFile(data))
            .catch(err => err),
        ]);
      }
  }

  const handleAddFile = fileItems => {
    setFiles(prevState => ({
      files: [
        ...prevState.files,
        {
          source: fileItems,
          options: {
            type: 'local',
          },
        },
      ],
    }));
  };

Doing absolutely nothing here, but somehow essentially required or else the component fails.

  const onUpdateFiles = thisFiles => {
    console.log(thisFiles);
  };

The component.

                  <FilePond
                    id="files"
                    name="files"
                    key="files"
                    ref={filePondGallery}
                    server={{
                      load: (source, load) => {
                        const myRequest = new Request(source);
                        fetch(myRequest).then(response => {
                          response.blob().then(myBlob => {
                            load(myBlob);
                          });
                        });
                      },
                    }}
                    instantUpload={false}
                    upload="false"
                    files={files.files}
                    allowMultiple
                    onupdatefiles={onUpdateFiles}
                  />

I have absolutely no idea why onupdatefiles is needed for this to function correctly when the function doesn't even do anything. But, without it, the component is dead. This should be documented, because it's a rather common use case.

michaelcuneo avatar Nov 26 '20 06:11 michaelcuneo

I've managed to get this working, in an extremely unconventional manner.

Adding files to filepond initially, then adding and / or removing files, 100% fails every single time, unless you add the function onupdatefiles = {} to the component, but leave it entirely blank. Using it to actually perform any updates to the local files, breaks the entire component, which is rather unusual. I've placed a function into the component, which does exactly nothing... but it does fix the component... maybe it should be changed to a bool, because obviously everyone wants to update their files.

I am so happy to read this, because I've been struggling with this identical issue for weeks now. Formik, S3, and FilePond seem to be breaking at the most minor changes, Having an onprocess callback removes the file preview upon process, if I remove onfileupdate nothing works properly, I've become demoralized. Have you found a workaround?

I too have tried scouring the internet for assistance with the react-filepond framework with limited success, adding S3 to the mix has diminished that same success further.

If I change any state variable from within Filepond even if the state is never utilized in the component, it breaks.

Dmarcotrigiano avatar May 13 '21 00:05 Dmarcotrigiano

onupdatefiles is used to sync the internal files list with an external list of files in state. When it's set to a function it will do this: https://github.com/pqina/react-filepond/blob/master/lib/index.js#L44

It's a bit of a hack to make this work. And it isn't working a 100% of the times it seems. There's always the option to use the vanilla JavaScript version of FilePond and build a small wrapper component around it to function inside your project.

rikschennink avatar May 17 '21 11:05 rikschennink