Yevgeniy Timchenko
Yevgeniy Timchenko

Reputation: 400

How to send a file with RTK Query from Redux Toolkit?

I am trying to use RTK Query mutations to upload a file to the API. Here is my mutation code:

    addBanner: builder.mutation({
          query(body) {
            return {
              url: `/api/banners`,
              method: 'POST',
              body,
            }
          },
        })

Here is how I generate the data for request.

    const [addBanner, { isBannerLoading }] = useAddBannerMutation();
    const new_banner = new FormData();    
    new_banner.append("file", my_file);
    new_banner.append("type", my_type);
    new_banner.append("title", my_title);
    addBanner(new_banner).unwrap().then( () => ... 

But I get an error:

A non-serializable value was detected in the state, in the path: `api.mutations.L-Mje7bYDfyNCC4NcxFD3.originalArgs.file`...

I know I can disable non-serializable check entirely through middleware, but I don't think it is an appropriate way of using Redux Toolkit and RTK. Without a file all works fine. Is there any right way of uploading files with RTK?

Upvotes: 14

Views: 29187

Answers (3)

Bhupender Keswani
Bhupender Keswani

Reputation: 1228

There is one more way to upload file without hampering the payload i.e. without need to flatten the object and using FormData,

So basically, if need to send file along with other nested object, then we can do it by encoding

const convertFileToBase64 = (file) => new Promise((resolve, reject) => {
  const reader = new FileReader();
  reader.readAsDataURL(file);
  reader.onload = () => resolve(reader.result); // Base64 string
  reader.onerror = (error) => reject(error);
});

and call above function to convert the file into base64 in following way

await convertFileToBase64(selectedFile); // in my case selected file is in blob.

Upvotes: 0

Hadi
Hadi

Reputation: 104

pass formData in the query.

Like this:

 addBanner: builder.mutation({
          query(body) {
            return {
              url: `/api/banners`,
              method: 'POST',
              body,
              formData: true,
            }
          },
        })

Upvotes: 0

phry
phry

Reputation: 44266

Edit: This has been fixed with @reduxjs/toolkit 1.6.1 - please update your package


I just opened an issue for this: https://github.com/reduxjs/redux-toolkit/issues/1239 - thanks for bringing it up!

For now, you'll probably have to disable that check (you can do so for a certain path in the state while keeping it for the rest with the ignoredPath option).

Upvotes: 8

Related Questions