ton1
ton1

Reputation: 7628

React-Redux Actions may not have an undefined "type" property

When I using redux-api-middleware on dispatching action, I got this error :

× Error: Actions may not have an undefined "type" property. Have you misspelled a constant?

I guess my applyMiddleware method is incorrect.

my index.js

import React from 'react'
import { render } from 'react-dom'
import { createStore, applyMiddleware } from 'redux'
import thunkMiddleware from 'redux-thunk'
import { Router } from 'react-router-dom'
import {apiMiddleware} from 'redux-api-middleware';

import Root from './containers/Root'
import rootReducer from './reducers'
import history from './constants/history'

const store = createStore(rootReducer, applyMiddleware(apiMiddleware, thunkMiddleware))

render(
    <Router history={history}>
        <Root store={store} />
    </Router>
   ,
    document.getElementById('root')
)

This package's readme applied middleware like below:

official doc's configureStore.js

import { createStore, applyMiddleware, combineReducers } from 'redux';
import { apiMiddleware } from 'redux-api-middleware';
import reducers from './reducers';

const reducer = combineReducers(reducers);
const createStoreWithMiddleware = applyMiddleware(apiMiddleware)(createStore);

export default function configureStore(initialState) {
  return createStoreWithMiddleware(reducer, initialState);
}

official doc's app.js

const store = configureStore(initialState);

But I don't know how to apply this in my structure, am I wrong something?

Add...

This is my code block

** LoginPage.js**

const LoginPage = ({dispatch, auth}) => {

    let emailInput, passwordInput;

    if(auth.user){
        return <Redirect to="/dashboard" />
    }

    return (
        <div>
            <h3>Login</h3>

            <form onSubmit={e => {
                e.preventDefault()
                if (!emailInput.value.trim() || !passwordInput.value.trim()) {
                    return
                }
                dispatch(processLogin({
                    email: emailInput.value.trim(),
                    password: passwordInput.value.trim(),

                }))
            }}>
                <input type="text" ref={node => emailInput = node} placeholder="[email protected]"/>
                <input type="password" ref={node => passwordInput = node} placeholder="password"/>
                <button type="submit">Submit</button>
            </form>
        </div>
    )
}

const mapStateToProps = (state) => {
    return {
        auth : state.auth
    };
}

export default connect(mapStateToProps)(LoginPage)

actions.js

export const processLogin = (user) => {
    return dispatch => {
        dispatch({
            [RSAA]: {
                endpoint: "http://localhost:3000/api/v1/sign-in",
                method: "POST",
                body: JSON.stringify({email: user.email, password: user.password}),
                headers: {
                    "Accept": "application/json",
                    "Content-Type": "application/json",
                },
                types: ['LOGIN', 'LOGIN_SUCCESS', 'LOGIN_FAILURE']
            }
        })
    }
}

Upvotes: 0

Views: 2234

Answers (2)

ton1
ton1

Reputation: 7628

Thanks for helping me @Yury and @Khatri

The problem was a silly mistake,

I chagned

import RSAA from 'redux-api-middleware'

to

import { RSAA } from 'redux-api-middleware'

and it's working.

Thanks for helps...

Upvotes: 2

Yury Tarabanko
Yury Tarabanko

Reputation: 45106

Your processLogin returns a thunk (ie. function not an object). You have to either add redux-thunk middleware before apiMiddleware to handle functions

const store = createStore(rootReducer, {}, applyMiddleware(thunkMiddleware, apiMiddleware))

or make processLogin to return an object.

export const processLogin = (user) => {
    return {
            [RSAA]: {
                endpoint: "http://localhost:3000/api/v1/sign-in",
                method: "POST",
                body: JSON.stringify({email: user.email, password: user.password}),
                headers: {
                    "Accept": "application/json",
                    "Content-Type": "application/json",
                },
                types: ['LOGIN', 'LOGIN_SUCCESS', 'LOGIN_FAILURE']
            }
        }
}

Upvotes: 1

Related Questions