1

I run redux-loop official example with a little change:

  1. Instead of fetch I use promise with a timeout.
  2. I added log middleware (copy-paste from redux.js.org tutorial).

side-effect function:

import {createStore, compose, applyMiddleware} from 'redux';
import {install, loop, Cmd} from 'redux-loop';

function fetchUser(userId) {
    return Promise.resolve((res, rej) => setTimeout(() => res(userId), 1000));
}

Actions:

function initAction() {
    return {
        type: 'INIT'
    };
}

function userFetchSuccessfulAction(user) {
    return {
        type: 'USER_FETCH_SUCCESSFUL',
        user
    };
}

function userFetchFailedAction(err) {
    return {
        type: 'USER_FETCH_ERROR',
        err
    };
}

Initial state:

const initialState = {
        initStarted: false,
        user: null,
        error: null
    };

Reducer:

function reducer(state = initialState, action) {
        console.log(action);  // I added this line
        switch (action.type) {
            case 'INIT':
                return loop(
                    {...state, initStarted: true},
                    Cmd.run(fetchUser, {
                        successActionCreator: userFetchSuccessfulAction,
                        failActionCreator: userFetchFailedAction,
                        args: ['1234']
                    })
                );

            case 'USER_FETCH_SUCCESSFUL':
                return {...state, user: action.user};

            case 'USER_FETCH_FAILED':
                return {...state, error: action.error};

            default:
                return state;
        }
    }

My custom log middleware:

    const logger = store => next => action => {
        console.group(action.type);
        console.info('dispatching', action);
        let result = next(action);
        console.log('next state', store.getState());
        console.groupEnd();
        return result
    };

Configure store:

const enhancer = compose(
        applyMiddleware(logger),
        install()
    );

    const store = createStore(reducer, initialState, enhancer);

Dispatching the first action to start it all: (my code)

store.dispatch(initAction());

output:

enter image description here


As you can see, the second action skipped my log middleware and also the last line of the log is not clear to me. Why the reducer received a function instead of the actual user object?

Stav Alfi
  • 13,139
  • 23
  • 99
  • 171

1 Answers1

2

Why the reducer received a function instead of the actual user object?

return Promise.resolve((res, rej) => setTimeout(() => res(userId), 1000));

Promise.resolve is used to create a promise already in the resolved state. It expects you to pass in what value the promise should resolve with, and in your case, you've asked it to resolve to a function.

You probably meant to do:

return new Promise((res, rej) => setTimeout(() => res(userId), 1000))
Nicholas Tower
  • 72,740
  • 7
  • 86
  • 98
  • Yeah, that's what I meant but I still see that the second action scripts my log middleware. Why? – Stav Alfi Oct 27 '18 at 13:19
  • As i'm unfamiliar with redux-loop, i'm unable to help with that part of your question. – Nicholas Tower Oct 27 '18 at 13:20
  • Okay, Thanks for the help :) – Stav Alfi Oct 27 '18 at 13:22
  • Yea switching to new Promise should address the second question. For the first, try switching the order of params to compose. const enhancer = compose( install(), applyMiddleware(logger) ); Ordering middleware can be confusing. The easiest thing is usually trial and error. https://redux-loop.js.org/docs/api-docs/install.html – bdwain Oct 28 '18 at 02:39