Search code examples
javascriptreactjsecmascript-6reduxfileapi

Extending or cloning File Web API object in Redux reducer to support other properties


I'm trying to keep an array of files that a user has selected to upload. Each file is a File object. I would like to add other properties to it, like 'progress' and 'status' so that I can present this data to a user when they begin the upload process.

The problem I'm having is that when I try to 'copy' a File object using Object.assign() or the JSON.parse(JSON.stringify(obj)) approach, I'm only ever getting back the properties that I have set myself, not the values inherent to the object.

This is an example of one of my attempts to use Object.assign():

Object.assign({}, state, {
    files: [
        ...state.files.slice(0, payload.index),
        Object.assign({}, state.files[payload.index], {
            status: 'UPLOADING',
            progress: 0
        }),
        ...state.files.slice(payload.index + 1)
    ]
})

Understandably, this causes me all sorts of problems...

What is a good way of keeping track of files and being able to extend their properties in a Redux-suitable manner?

Thanks to all in advance.


Solution

  • Just don't try to store your extra properties on the File object. Instead store them as siblings on a parent object:

    // INIT case
    return {
        ...state,
        files: [
            ...state.files,
            { fileObject, status: "INITIAL" }
        ]
    };
    
    // UPDATE case
    return {
        ...state,
        files: [
            ...state.files.slice(0, payload.index),
            { ...state.files[payload.index], status: "UPLOADING", progress: 0 },
            ...state.files.slize(payload.index + 1)
        ]
    };
    

    In this scheme:

    // fileObject is the File
    const { fileObject, status, progress } = state.files[2];