0

I am new to using redux-pack but like the way the promise approach really cleans up the code and makes each step very clear. However I have hit a problem where the promise seems to vanish and and error gets thrown. My code looks like the following:

actions.js

import * as types from './action_types';
import * as services from '../services';

export const login = (email, password) ({type: types.LOGIN, promise: services.login(email, password)});

services.js

const checkResponse = (response) => {
    if (response.ok) {
        return response;
    } else {
        let error = new Error(response.statusText);
        error.response = response;
        throw error;
    }
};

export const login = (email, passowrd) => {
    let request = new Request('/login', {method: 'POST', body: {email: email, password: password}});

    return fetch('/login', request)
        .then(checkResponse)
        .then(response => response.json())
        .catch(error => error);
};

reducer.js

import handle from 'redux-pack';
import * as actions from '../actions';

const INITIAL_STATE = {
    loggedin: false,
    isworking: false,
    err: null,
};

export default function reducer(state = INITIAL_STATE, action) {
    const { type, payload } = action;

    switch (type) {

    case actions.LOGIN:
        return handle(state, action, {
            start: prevState) => ({...prevState, isworking: true, err: null}),
            finish: prevState => ({ ...prevState, isworking: false }),
            failure: prevState => ({ ...prevState, err: payload }),
            success: prevState => ({ ...prevState, loggedin: payload.ok })
        });
    default:
        return state;
    }
}

However when I run this code I get the following error when I trigger the action:

TypeError: Object is not a function (near '...(0, _reduxPack2.default)...')

I had instrumented the code with console output and could see the following steps take place directly before the error:

[Log] Login login, called +0ms (client.js, line 7245)
[Log] Login props = {"match":{"path":"/login","url":"/login","isExact":true,"params":{}},"location":{"pathname":"/login","state":{"from":"/authRoute"},"search":"","hash":"","key":"6gnu0d"},"history":{"length":72,"action":"REPLACE","location":{"pathname":"/login","state":{"from":"/authRoute"},"search":"","hash":"","key":"6gnu0d"}},"isworking":false,"loggedin":false,"err":null} +1ms (client.js, line 7245)
[Log] Login mapDispatchToProps, login dispatched. +0ms (client.js, line 7245)
[Log] actions login, called +0ms (client.js, line 7245)
[Log] services login, called. +0ms (client.js, line 7245)
[Log] actions promise = [object Promise] +2ms (client.js, line 7245)
[Log] actions action = {"type":"LOGIN","promise":{}} +0ms (client.js, line 7245)
[Log] reducer reducer called +4s (client.js, line 7245)
[Log] reducer state is: {"loggedin":false,"isworking":false,"err":null} +0ms (client.js, line 7245)
[Log] reducer action type is: "LOGIN" +0ms (client.js, line 7245)
[Log] reducer action promise is: undefined +0ms (client.js, line 7245)
[Log] reducer action payload is: undefined +0ms (client.js, line 7245)

I also had some expected output in the start function in the reducer and that was never called. In the above 'Login' is the React component and I can see it makes the call, the props have the expected state and the login call is dispatched. I then see the action call the service, get the generated promise and build the full action. The reducer is called and the state looks as expected, the action type is as expected but the promise part of the action is undefined, I suspect this could be what is causing the call to the react-pack handler to throw an error. Any suggestions on what to try or where to look are welcome!

JSDevGuy
  • 127
  • 2
  • 11
  • I decided to stringily the entire action in the reducer to see what I had (rather than look at a few parts) and what I see is: [Log] reducer action : {"type":"LOGIN","meta":{"redux-pack/LIFECYCLE":"start","redux-pack/TRANSACTION":"893be9d0-6634-4e5e-b54f-7d4ce625eedb"}} +0ms (client.js, line 7247) Oddly I do not see the promise that I could see in the preceding action! – JSDevGuy Jun 11 '18 at 00:44

1 Answers1

0

I believe your promise is being lost in the checkResponse throw. Make sure it returns a rejected promise instead, like below:

const checkResponse = (response) => {
    if (!response.ok) {
      let error = new Error(response.statusText);
      error.response = response;
      return Promise.reject(error);
    }
    return response;
};
Guilherme Lemmi
  • 3,271
  • 7
  • 30
  • 30
  • 1
    Hi Guilherme, good suggestion I have tried this and the code is much more aligned to the expected Promise behavior so I will keep the code change but I still hit the same problem :( It is as if some where between the action and the reducer the promise is stripped??!! – JSDevGuy Jun 09 '18 at 07:14