Iga
Iga

Reputation: 333

Why during action call inn component occurs "Actions must be plain objects." - error?

In my project I have action call, service(for http fetch requests). In action I call service and after its executing I make dispatch in order to call reducer. In my component I call this action via mapDispatchToProps. On component loading I get error and dont quite understand why

http service:

export class HttpService {
    static HEADERS = {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
        'Host': 'app.heavyrepair.ru',
        'User-Agent': 'myAp'
    };

    static async get(url, requestParams) {
        try {
            return await request(url,'GET', requestParams)
        } catch (e) {
            console.log('REQUEST error. GET request error text: ', e)
            throw e
        }
    }
    static async post(url, requestParams) {
        try {
            return await request(url, 'POST', requestParams)
        } catch (e) {
            console.log('REQUEST error. POST request error text: ', e)
            throw e
        }
    }
    static async delete(url, requestParams) {
        try {
            return await request(url, 'DELETE', requestParams)
        } catch (e) {
            console.log('REQUEST error. DELETE request error text: ', e)
            throw e
        }
    }
}

async function request(url, method = 'GET', requestParams) {
    const config = {
        method,
        headers: HttpService.HEADERS,
    };

    if (method === 'POST') {
        config.body = JSON.stringify(requestParams)
    }

    const response = await fetch(url, config);

    return await response.json()
}

action:

export const fetchModels = () => (dispatch, getState) => {
    dispatch({
        type: REQUEST_MODELS,
        payload: true,
    });

    const url = `http://localhost:8000/api/models`;

    return HttpService.get(url)
        .then(response => {
            dispatch({
                type: REQUEST_MODELS,
                payload: false,
            });
            dispatch({
                type: RECEIVE_MODELS,
                payload: response,
            });
        });
};

and call action in component did mount:

class MainPage extends Component {
    constructor(props) {
        super(props);
    }

    componentDidMount() {
        this.props.fetchModels()
            .then(this.setState({loading: false}));
    }

    render() {
        const {
            models,
            modelsLoading
        } = this.props;

        return (
            <div className="block-model-list">
             ...
            </div>
        );
    }
}

const mapDispatchToProps = dispatch => (
    {
        fetchModels: () => dispatch(fetchModels()),
    }
);


const mapStateToProps = state => {
    return {
        models        : state.models,
        modelsLoading : state.modelsLoading,
    }
};

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(MainPage));

error redux-logger.js?5d82:1 Uncaught Error: Actions must be plain objects. Use custom middleware for async actions. happens in didmount on action call. Why?

Upvotes: 0

Views: 38

Answers (1)

Prakhar
Prakhar

Reputation: 1485

Actions in redux should be plain JavaScript objects. However by doing fetchModels: () => dispatch(fetchModels()) you are dispatching the result of fetchModels() function execution as an action.

In order to perform asynchronous operations inside the action creator, custom middleware has to be used. One such popularly used middleware is Redux Thunk . It will let you write async action creators.

Upvotes: 1

Related Questions