javascriptreactjsfile-uploadreact-reduxasyncfileupload

Returning payload from async action creator - React js


I'm new to javascript and the React ecosystem and I'm working on an app that let's the user upload a profile photo. I researched uploading a file to Cloudinary using Superagent which is great and used it in the upload component. Since I'm using Redux for handling state I refactored that upload code in the component into an upload action creator. That's definitely working and uploading the file to Cloudinary. In the code I have I'm trying to return the file url, which prints when I console.log it. I just really need to make this the action creator's payload so I can attach it to state in the reducer. I feel like I'm so close, but yet I can't get the file url to return as the action's payload.

Once I do that I will be able to input the value in a hidden field as a ref in the form that will post to the firebase database.

If someone knows what I mean and can just show me what I'm doing wrong, I'll be most appreciative.

This is the ActionCreator:

import request from 'superagent';
import {
    UPLOAD_IMAGE,
    FETCH_PARTNERS 
} from './types';

const UPLOAD_PRESET = 'testPreset1';
const UPLOAD_URL = 'https://api.cloudinary.com/v1_1/duqn30c4x/image/upload';

export const dropImage = file => {
    let uploadedFileUrl = '';
    let data;
    let fileURL;
    let upload = request.post(UPLOAD_URL)
                        .field('upload_preset', UPLOAD_PRESET)
                        .field('file', file)
    upload.end((err, response) => {
        if(err) {
            console.log(err);
        }
        if(response.body.secure_url !== '') {
            uploadedFileUrl = response.body;
            return uploadedFileUrl.secure_url, console.log(uploadedFileUrl.secure_url);
        }
    })
    return{
        type: UPLOAD_IMAGE,
        payload: uploadedFileUrl
    }
}

This is the Image Reducer:

import {
    UPLOAD_IMAGE
} from '../actions/types';

const INITIAL_STATE = {};


export default (state = INITIAL_STATE, action) => {
    console.log(state, action.payload);
    switch (action.type) {
        case UPLOAD_IMAGE:
        return [ ...state, action.payload ]
    }
    return state;
}

Thanks a lot for taking a look.

Alvin


Solution

  • use redux-thunk to dispatch from an async action.

    export const dropImage = file => {
        return (dispatch, getState)=>{
            let uploadedFileUrl = '';
            let data;
            let fileURL;
            let upload = request.post(UPLOAD_URL)
                                .field('upload_preset', UPLOAD_PRESET)
                                .field('file', file)
            upload.end((err, response) => {
                if(err) {
                    console.log(err);
                }
                if(response.body.secure_url !== '') {
                    uploadedFileUrl = response.body;
                    dispatch({
                        type: UPLOAD_IMAGE,
                        payload: uploadedFileUrl
                    })
                    console.log(uploadedFileUrl.secure_url);
                }
            })
        }
    }