0

I am doing the assignment no 4 from the course "Front end web Development with React" in Coursera. Here I want to submit a form data to the server and then show an alert to the user. And The code works fine, the alert is also showing but then the error happens.

From related posts in stack overflow i figured out that the problem is somehow related to returning a redux action which must have a type property. But I cant figure out how i return this in this manner. As i don't have to do any action. I just need to show an alert.


export const postFeedback = (firstname, lastname, email, telnum, agree, contactType, message) => {
        const newFeedback = {
            firstname:firstname,
            lastname:lastname,
            email:email,
            telnum:telnum,
            agree:agree,
            contactType: contactType,
            message:message,
        }
        newFeedback.date = new Date().toISOString();
        return fetch(baseUrl + 'feedback', {
            method: "POST",
            body: JSON.stringify(newFeedback),
            headers: {
                "content-Type": "application/json"
            },
            credentials: "same-origin"
        })
        .then(res => {
            if (res.ok){
                return res
            }else{
                var error = new Error('Error '+ res.status + ': '+res.statusText);
                error.response = res;
                throw error;
            }},
            error => {
                throw error;
            })
            .then(response => response.json())
            .then(response => alert(response))
            .catch(error =>  { console.log('post feedback', error.message);
             alert('Your feedback could not be sent\nError: '+error.message);
             });
    }

Everything works fine. the feedback is saved in the database and the alert is also shown and then the error "Error: Actions must be plain objects. Use custom middleware for async actions." happened.

  • Also add the code you call this function `postFeedback` – Sibiraj PR Mar 26 '19 at 06:32
  • If from the action you aren't updating the reduces, you can simply call the action instead of dispatching it. If you do dispatch an action which executes asynchronously, you would need to configure redux-thunk as a middleware – Shubham Khatri Mar 26 '19 at 06:43

3 Answers3

1

Finally figured it out by adding an action that doesn't do anything. Here is the code that works like a charm. I am posting it in case someone may be helped by

export const addFeedback = () => ({
    type: ActionTypes.ADD_FEEDBCK,
})
export const postFeedback = (firstname, lastname, email, telnum, agree, contactType, message) =>
 dispatch => {
        const newFeedback = {
            firstname:firstname,
            lastname:lastname,
            email:email,
            telnum:telnum,
            agree:agree,
            contactType: contactType,
            message:message,
        }
        newFeedback.date = new Date().toISOString();
        return fetch(baseUrl + 'feedback', {
            method: "POST",
            body: JSON.stringify(newFeedback),
            headers: {
                "content-Type": "application/json"
            },
            credentials: "same-origin"
        })
        .then(res => {
            if (res.ok){
                return res
            }else{
                var error = new Error('Error '+ res.status + ': '+res.statusText);
                error.response = res;
                throw error;
            }},
            error => {
                throw error;
            })
            .then(response =>  response.json())
            .then(res => {
                console.log(res);
                alert(JSON.stringify(res));
                return dispatch(addFeedback());
            })
            .catch(error =>  { console.log('post feedback', error.message);
             alert('Your feedback could not be sent\nError: '+error.message);
             });
    }
0

If Redux is part of your app architecture, you may want to use redux-thunk middleware: https://www.npmjs.com/package/redux-thunk

Here's a common setup for your redux store:

import {createStore, applyMiddleware} from 'redux';  
import rootReducer from '../reducers/rootReducer';  
import thunk from 'redux-thunk';

export default function configureStore() {  
  return createStore(
    rootReducer,
    applyMiddleware(thunk)
  );
}
...

And here's a detailed answer by Dan Abramov on why we may want to use it: https://stackoverflow.com/a/34599594/5391520

  • I already have this set up. All the part of the other code is working fine. I already applied postComment that also worked fine without any error. But there was an action "addComment" that was attached so i can simply return the action. But in this case there I have no action to return. – Iqbal Mohammad Rhidwan Mar 26 '19 at 06:58
0

Actions are pure functions and it should return objects. In general they can handle synchronous operations well, but for asynchronous operations you should return function with dispatch parameter or can use middle-ware.

Example:-

const myAction = () => {
    return (dispatch) => {
        let promise =  new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve({type:'my_action', payload:{'sample': 'data'}})
            }, 1000)
        });

        promise.then((rsp) => {
            dispatch(rsp);
        })

        return promise;
    }
}
Nagarjuna
  • 61
  • 2