# Unable to upload file using EuiFilePicker

**URL:** <https://discuss.elastic.co/t/unable-to-upload-file-using-euifilepicker/271955>\
**Category:** Kibana\
**Tags:** kibana-plugin-development\
**Created:** [May 3, 2021, 9:30am UTC](https://discuss.elastic.co/t/unable-to-upload-file-using-euifilepicker/271955 "2021-05-03T09:30:29Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![praveer](https://avatars.discourse-cdn.com/v4/letter/p/41988e/32.png) [@praveer](https://discuss.elastic.co/u/praveer)\
**Post date:** [May 3, 2021, 9:30am UTC](https://discuss.elastic.co/t/unable-to-upload-file-using-euifilepicker/271955/1 "2021-05-03T09:30:29Z")

</div>

Hi Team,

I have created a custom plugin and i have a requirement to upload file to server. I am trying to do it using EuiFilePicker. API which I am using to upload file is accepting data in form-data format. Below is my code.

component.ts :-

```auto
    const [files, setFiles] = useState({});
    const [large, setLarge] = useState(true);

    const onFileChange = files => {
        setFiles(files);
    };

    const onSubmit = () => {
        const data = new FormData();
        data.append('file', files[0]);
        data.append('remark', 'Test');
        data.append('case_id', 'INC-000001');
        
        const submitRequestOptions = {
            method: 'POST',
            body: data
        }

        props.http.post(window.location.origin + '/casemanagement/files/', submitRequestOptions).then((res) => {
            console.log("Success Response", res);

        }).catch((error: ResponseError) => {
            console.log("Error", error);
        });
    }

    const renderFiles = () => {
        if (files.length > 0) {
            return (
                <ul>
                    {Object.keys(files).map((item, i) => (
                        <li key={i}>
                            <strong>{files[item].name}</strong> ({files[item].size} bytes)
                        </li>
                    ))}
                </ul>
            );
        } else {
            return (
                <p>Add some files to see a demo of retrieving from the FileList</p>
            );
        }
    };

    return (
        <EuiPanel paddingSize="m" className="mr10 ml10">
            <EuiFlexGroup>
                <EuiFlexItem>
                    <EuiFilePicker
                        id="asdf2"
                        multiple
                        initialPromptText="Select or drag and drop multiple files"
                        onChange={files => {
                            onFileChange(files);
                        }}
                        display={large ? 'large' : 'default'}
                        aria-label="Use aria labels when no actual label is in use"
                    />
                </EuiFlexItem>
                <EuiFlexItem>
                    <EuiText>
                        <h3>Files attached</h3>
                        {renderFiles()}
                    </EuiText>
                </EuiFlexItem>
            </EuiFlexGroup>
            <EuiButton fill id='btnStep4Submit' color="primary" onClick={() => { onSubmit()}}>
                <strong>Submit</strong>
            </EuiButton>
        </EuiPanel>
    )

```

Server-route-index.ts api calling code.

```auto
router.post(
    {
      path: '/casemanagement/files/',
      validate: {
        body: schema.any(),
      },
    },
    async (context, request, response) => {
      const requestOptions = {
        method: 'POST',
        headers: { 'Content-Type': 'multipart/form-data', 'Cluster': process.env["cluster"], 'Authorization': request.headers.authorization },
        body: request.body,
        agent: httpsAgent
      };
      console.log("Request - ", request.body)
      return fetch(serverURL + '/casemanagement/cases/files/', requestOptions)
        .then(resp => {
          logger.info('Correlation-App : casemanagement close success');
          console.log("Response", resp);
          if (resp.status == 201) {
            return resp
          } else {
            throw new Error(resp)
          }
        }).then(res => {
          return response.ok({
            body: {
              Response: res
            },
          });
        })
        .catch(async (err) => {
          logger.info('Correlation-App : ' + err);
          let message_ = await err.text().then(mm => {
            return mm;
          });
          var resp_ = response.custom({
            body: {
              message: message_
            },
            statusCode: err.status
          });
          return resp_;
        });
    }
  );

```

I have tried uploading file through postman it works fine below is the screenshot of postman

 ![FileUploadPostman](https://us1.discourse-cdn.com/elastic/original/3X/7/c/7c584a2cfcf2ea735be755d67fe00b17ba078fb9.png)

If any example is there on how to upload file it would be better.

Thanks & Regards  
Praveer

---

<div class="post-metadata">

**Author:** ![thompsongl](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/thompsongl/32/85843_2.png) [@thompsongl](https://discuss.elastic.co/u/thompsongl)\
**Post date:** [May 3, 2021, 3:07pm UTC](https://discuss.elastic.co/t/unable-to-upload-file-using-euifilepicker/271955/2 "2021-05-03T15:07:14Z")

</div>

Hi @praveer  
Can you confirm that the file data present (`files[0]`) when calling `onSubmit` is correct or incorrect?  
If the data is correct, then EuiFIlePicker is working as expected and the problem likely lies with the `onSubmit` function.

---

<div class="post-metadata">

**Author:** ![praveer](https://avatars.discourse-cdn.com/v4/letter/p/41988e/32.png) [@praveer](https://discuss.elastic.co/u/praveer)\
**Post date:** [May 4, 2021, 10:40am UTC](https://discuss.elastic.co/t/unable-to-upload-file-using-euifilepicker/271955/3 "2021-05-04T10:40:58Z")

</div>

Hi @thompsongl

Below is the screen of console log of files[0].

 ![File0Consolelog](https://us1.discourse-cdn.com/elastic/original/3X/7/f/7ff8be7dcc23f1c475ccf90fb97245f4cab6d0fa.png)

This is what I am passing to my api.

---

<div class="post-metadata">

**Author:** ![thompsongl](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/thompsongl/32/85843_2.png) [@thompsongl](https://discuss.elastic.co/u/thompsongl)\
**Post date:** [May 4, 2021, 2:03pm UTC](https://discuss.elastic.co/t/unable-to-upload-file-using-euifilepicker/271955/4 "2021-05-04T14:03:34Z")

</div>

Thanks. It appears that EuiFilePicker is working as expected. The error is coming from the HTTP request, but I'm familiar enough with plugin APIs to diagnose the issue beyond that.  
I'll ping someone with more knowledge on the subject.

---

<div class="post-metadata">

**Author:** ![afharo](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/afharo/32/75202_2.png) [@afharo](https://discuss.elastic.co/u/afharo)\
**Post date:** [May 4, 2021, 4:57pm UTC](https://discuss.elastic.co/t/unable-to-upload-file-using-euifilepicker/271955/5 "2021-05-04T16:57:03Z")

</div>

I think the problem is coming from the `submitRequestOptions`. I believe the HTTP client is not automatically appending the Header to post the `FormData`. So the body-parser on the server doesn't know how to handle the contents of the body and fails with Bad request.

Would you mind manually adding the property `headers: {'content-type': 'multipart/form-data'}` to the `submitRequestOptions` and try if that fixes the issue?

---

<div class="post-metadata">

**Author:** ![praveer](https://avatars.discourse-cdn.com/v4/letter/p/41988e/32.png) [@praveer](https://discuss.elastic.co/u/praveer)\
**Post date:** [May 6, 2021, 3:51pm UTC](https://discuss.elastic.co/t/unable-to-upload-file-using-euifilepicker/271955/6 "2021-05-06T15:51:03Z")

</div>

Hi @afharo ,

I tried passing `headers: {'content-type': 'multipart/form-data'}` as shown below

```auto
const onSubmit = () => {
        const data = new FormData();
        data.append('file', files[0]);
        data.append('remark', 'Test');
        data.append('case_id', 'INC-000001');
        console.log("Files - ", files[0]);
        const submitRequestOptions = {
            method: 'POST',
            headers: { 'Content-Type': 'multipart/form-data' },
            body: data
        }

        props.http.post(window.location.origin + '/casemanagement/files/', submitRequestOptions).then((res) => {
            console.log("Success Response", res);

        }).catch((error: ResponseError) => {
            console.log("Error", error);
        });
    }

```

Server-route-index.ts api calling code.

```auto
router.post(
    {
      path: '/casemanagement/files/',
      validate: {
        body: schema.any(),
      },
    },
    async (context, request, response) => {
      const requestOptions = {
        method: 'POST',
        headers: { 'Content-Type': 'multipart/form-data', 'Cluster': process.env["cluster"], 'Authorization': request.headers.authorization },
        body: request.body,
        agent: httpsAgent
      };
      console.log("Request - ", request.body)
      return fetch(serverURL + '/casemanagement/cases/files/', requestOptions)
        .then(resp => {
          logger.info('Correlation-App : casemanagement close success');
          console.log("Response", resp);
          if (resp.status == 202) {
            return resp
          } else {
            throw new Error(resp)
          }
        }).then(res => {
          return response.ok({
            body: {
              Response: res
            },
          });
        })
        .catch(async (err) => {
          logger.info('Correlation-App : ' + err);
          let message_ = await err.text().then(mm => {
            return mm;
          });
          var resp_ = response.custom({
            body: {
              message: message_
            },
            statusCode: err.status
          });
          return resp_;
        });
    }
  );

```

Below are the attached screen shot of the payload passed in headers and its response  
 ![fileFormDataPayload](https://us1.discourse-cdn.com/elastic/original/3X/e/a/ea44db0280549971878c405bb8382cdf31dc5b69.png)

![filleFormDataResponse](https://us1.discourse-cdn.com/elastic/original/3X/c/b/cb5cf160679ce000edc7f4d5ce51efbaa5dfa2ce.png)

Can you please help.

---

<div class="post-metadata">

**Author:** ![afharo](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/afharo/32/75202_2.png) [@afharo](https://discuss.elastic.co/u/afharo)\
**Post date:** [May 6, 2021, 4:51pm UTC](https://discuss.elastic.co/t/unable-to-upload-file-using-euifilepicker/271955/7 "2021-05-06T16:51:24Z")

</div>

From the response, I get that the `multipart` header is missing the boundary. You might need to add it. If you look at the headers Postman adds, when using `Content-Type: 'multipart/form-data'`, the `boundary=` bit needs to be added ([MDN Web docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type)).

Here are some examples of possible options: [javascript - fetch - Missing boundary in multipart/form-data POST - Stack Overflow](https://stackoverflow.com/questions/39280438/fetch-missing-boundary-in-multipart-form-data-post). Apparently, some users made it work by explicitly setting `Content-Type: undefined`, and letting `fetch` to populate it automatically (FYI, we use `fetch` under the hood). Others had to add `'Accept': '*/*'` to the request as well 🤷‍♂️

---

<div class="post-metadata">

**Author:** ![praveer](https://avatars.discourse-cdn.com/v4/letter/p/41988e/32.png) [@praveer](https://discuss.elastic.co/u/praveer)\
**Post date:** [May 17, 2021, 4:37pm UTC](https://discuss.elastic.co/t/unable-to-upload-file-using-euifilepicker/271955/8 "2021-05-17T16:37:59Z")

</div>

Hi @afharo,

I tried ur suggestion, but in the above suggestion file is going as binary format and getting bad request error.

In EUIFilePicker how can I get file path as I am trying to send payload as below for that I need to get the file path of uploaded file, but I couldn't find it in EUIFilePicker

```auto
var formdata = new FormData();
formdata.append("file", fileInput.files[0], "/C:/Users/Praveer.Nair/Desktop/cases.json");
formdata.append("remark", "Test");
formdata.append("case_id", "INC-000001");

var requestOptions = {
  method: 'POST',
  headers: myHeaders,
  body: formdata,
  redirect: 'follow'
};

```

---

<div class="post-metadata">

**Author:** ![afharo](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/afharo/32/75202_2.png) [@afharo](https://discuss.elastic.co/u/afharo)\
**Post date:** [May 18, 2021, 4:32pm UTC](https://discuss.elastic.co/t/unable-to-upload-file-using-euifilepicker/271955/9 "2021-05-18T16:32:03Z")

</div>

I think @thompsongl can help with that better than I can 🙂

---

<div class="post-metadata">

**Author:** ![thompsongl](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/thompsongl/32/85843_2.png) [@thompsongl](https://discuss.elastic.co/u/thompsongl)\
**Post date:** [May 18, 2021, 5:00pm UTC](https://discuss.elastic.co/t/unable-to-upload-file-using-euifilepicker/271955/10 "2021-05-18T17:00:29Z")

</div>

EuiFilePicker is really just a styled native [HTML \<input type="file"\> element,](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file) so all the data you get is from the Web API: [File - Web APIs | MDN](https://developer.mozilla.org/en-US/docs/Web/API/File).  
Looks like `webkitRelativePath` might be helpful, but EUI does not actually handle the file itself or provide any data beyond the Web API.

---

<div class="post-metadata">

**Author:** ![praveer](https://avatars.discourse-cdn.com/v4/letter/p/41988e/32.png) [@praveer](https://discuss.elastic.co/u/praveer)\
**Post date:** [May 24, 2021, 10:05am UTC](https://discuss.elastic.co/t/unable-to-upload-file-using-euifilepicker/271955/11 "2021-05-24T10:05:11Z")

</div>

hi @thompsongl ,

WebkitRelativePath is coming empty as shown in below screen shot.

 ![image](https://us1.discourse-cdn.com/elastic/original/3X/f/d/fd40595750da07a805b0dc4c88ff3eb4da6bb190.png)

---

<div class="post-metadata">

**Author:** ![thompsongl](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/thompsongl/32/85843_2.png) [@thompsongl](https://discuss.elastic.co/u/thompsongl)\
**Post date:** [May 24, 2021, 2:34pm UTC](https://discuss.elastic.co/t/unable-to-upload-file-using-euifilepicker/271955/12 "2021-05-24T14:34:28Z")

</div>

I just reread the spec and `webkitRelativePath` will not be helpful for your case:

> The `File.webkitRelativePath` is a read-only property that contains a [`USVString`](https://developer.mozilla.org/en-US/docs/Web/API/USVString) which specifies the file's path relative to the directory selected by the user in an [`<input>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input) element with its [`webkitdirectory`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-webkitdirectory) attribute set.

It only works when selecting directories and when using the `webkitdirectory` attribute.  
Unfortunately the data you want is not available in the Web API.  
Although EuiFilePicker cannot provide this data, `formdata.append("file", fileInput.files[0])` appears to be sufficient per the `FormData` spec: [FormData: append() method - Web APIs | MDN](https://developer.mozilla.org/en-US/docs/Web/API/FormData/append)

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [June 21, 2021, 2:34pm UTC](https://discuss.elastic.co/t/unable-to-upload-file-using-euifilepicker/271955/13 "2021-06-21T14:34:50Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
