Redux: How to do File Upload?

Created on 11 Sep 2015  路  4Comments  路  Source: reduxjs/redux

Hello,

I am trying to upload a file from a form which I want to be managed by Redux. if I understand everything correctly, I have to send plain objects as actions. From the input[type=file] field, I get back a File object as the "value". If I try to send that, it will be stringified as C:\fakepath\Blablabla.file. How do I handle this with Redux?

E.g. lets say I for example have a action UPDATE_FORM_FIELD and then another action SUBMIT_FORM.

  • UPDATE_FORM_FIELD sends an action with a payload of field and value.
  • SUBMIT_FORM gets the current state with redux-thunks getState() function, and then dispatches that to a redux-api-middleware action, which takes care of POSTing the REST API, and dispatching SUBMIT_FORM_SUCCESS / SUBMIT_FORM_FAILURE types.

I see three possible solutions:

  1. (which I hope for): Someone here has a brilliant idea on how to solve this :)
  2. I don't use Redux for managing this forms state, and take care of the REST API calls manually without redux-api-middleware.
  3. I read the entire file to memory (should be fine, it's only a couple of KB), and assign that as value.
question

Most helpful comment

export function uploadFile(file) {
  return (dispatch, getState) => {
    const { values } = getState().certificate.form;

    const formData = new FormData();
    _.forEach(_.keys(values), (key) => {
      formData.append(key, values[key]);
    });
    formData.append('file', file);

    dispatch({
      [CALL_API]: {
        types: [SUBMIT_FORM, SUBMIT_FORM_SUCCESS, SUBMIT_FORM_FAILURE],
        endpoint: 'certificate',
        method: 'post',
        payload: formData,
      },
    });
  };
}

This seemed to work fine for me. But I am open to better suggestions.

(_Note, I don't use the standard redux-api-middleware, but rather a version based on axios, so YMMV, when it comes to passing down FormData objects)_.

All 4 comments

Since you can't set the value of a file input (the browser will prevent it), I wouldn't try to manage state of the file. Instead, make it something you can reference and query for its current state to pass into your action creator for form submission.

This is a bit of a toughie because of the security restriction.

export function uploadFile(file) {
  return (dispatch, getState) => {
    const { values } = getState().certificate.form;

    const formData = new FormData();
    _.forEach(_.keys(values), (key) => {
      formData.append(key, values[key]);
    });
    formData.append('file', file);

    dispatch({
      [CALL_API]: {
        types: [SUBMIT_FORM, SUBMIT_FORM_SUCCESS, SUBMIT_FORM_FAILURE],
        endpoint: 'certificate',
        method: 'post',
        payload: formData,
      },
    });
  };
}

This seemed to work fine for me. But I am open to better suggestions.

(_Note, I don't use the standard redux-api-middleware, but rather a version based on axios, so YMMV, when it comes to passing down FormData objects)_.

@gaearon your link got 404ed, and I feel the community would love to see what would you do. 馃

Was this page helpful?
0 / 5 - 0 ratings

Related issues

cloudfroster picture cloudfroster  路  3Comments

dmitry-zaets picture dmitry-zaets  路  3Comments

rui-ktei picture rui-ktei  路  3Comments

olalonde picture olalonde  路  3Comments

elado picture elado  路  3Comments