0

I am using redux-thunk and redux-promise together and somehow redux-thunk middleware does not get called and i get an error.

THIS IS MY SETUP

import React from 'react';
import ReactDOM from 'react-dom';
import {BrowserRouter} from 'react-router-dom'
import {Provider} from 'react-redux'
import { composeWithDevTools } from 'redux-devtools-extension';
import {createStore, applyMiddleware} from 'redux'
import thunk from 'redux-thunk'
import promiseMiddleware from 'redux-promise';

import {ThemeProvider} from "@material-ui/core/styles"
import theme from "./components/ui/Theme"
import reducers from './reducers/index'
import './index.css';
import App from './App';

const middleware =[thunk, promiseMiddleware]

const store = createStore(
  reducers,
  composeWithDevTools(applyMiddleware(...middleware))
)



ReactDOM.render(
  <Provider store={store}>
    <ThemeProvider theme={theme}>
      <BrowserRouter>
        <App />
      </BrowserRouter>
    </ThemeProvider>
  </Provider>  
  ,
  document.getElementById('root')
);

THIS IS MY ACTION CREATOR

export const authUser =  () => { 

    const res = axios.get("http://localhost:3002/api/users/auth", {withCredentials: true})
      
    return {type: AUTH_USER, payload: res.data}
}

This is my Higher Order AUTH Component which renders another component and AFTER DISPATCHING ACTION IN ComponentDidMount, based on the results I want to change routes.

import React from 'react'
import {connect} from 'react-redux'
import {withRouter} from 'react-router-dom'

import CircularProgress from '@material-ui/core/CircularProgress';
import {authUser} from '../actions/user'


export default function(WrappedComponent, isRestricted){
    class Auth extends React.Component {

    state = {
        loading: true
    }
    
        componentDidMount() {
        
        this.props.dispatch(authUser()).then(() => {
            this.setState({loading: false})
            
            // if(!this.props.user.isAuth && isRestricted) {
            //     this.props.history.push('/joinus')
            // }
            // else if (this.props.user.isAuth && isRestricted === null) {
            //     this.props.history.push('/')
            // }
        }) 
    }

    render() {

        if(this.state.loading) {
        
            return (
                <CircularProgress />
            )
        }


        return (
            <div>
                <WrappedComponent  {...this.props} />
            </div>
        )
    }  
        
    }

    function mapStateToProps (state) {
        return {
            user: state.user.userData
        }
    }
    
    return  connect(mapStateToProps)(withRouter(Auth))
}

AND FINALLY THIS IS THE ERROR I GET.

https://i.stack.imgur.com/jDrib.jpg OR https://prnt.sc/tkcs0m

(Unhandled Rejection (TypeError): this.props.dispatch(…).then is not a function )

If I dont use .then() in ComponentDidMount, then I get undefined. ALSO If I dispatch inside of AXIOS request by adding .then(), this is another error I get

(Error: Actions must be plain objects. Use custom middleware for async actions.) https://i.stack.imgur.com/FG8Ov.jpg OR https://prnt.sc/tkcsqy

Can
  • 1
  • 2
  • you are not passing the props. check this https://reactjs.org/docs/react-without-es6.html#setting-the-initial-state use constructor. – Monzoor Tamal Jul 18 '20 at 19:38
  • problem is not with dispatch function but .then(). I should be able to use that. I mean thats what I expect :D – Can Jul 18 '20 at 19:55
  • The problem is in your axios call. https://github.com/axios/axios read the documentation. axios get returns a promise. use can use try catch or async await. – Monzoor Tamal Jul 18 '20 at 20:06
  • should not It be handled by middlewares ?. It worked but now I get another error and I think I learned these concepts really wrong :( – Can Jul 18 '20 at 20:28
  • can i get a upvote for that? – Monzoor Tamal Jul 18 '20 at 20:42
  • Since you just commented I am not able to do that – Can Jul 18 '20 at 20:45

2 Answers2

0

after adding async await to axios call It worked(I thought It should be handled by middlewares) but now I get another error in my Header component

    useEffect(() => {
        
        props.dispatch(actions.authUser()).then(() => {
            console.log(props, actions)
            if(props.user.isAuth) setToggleLogOut(true)
        })

        window.addEventListener('scroll', ()=> {
            window.scrollY > 0 ? setToggleHeader(true) : setToggleHeader(false)
        });
    }, [props.value])

    const handleLogOut = () => {
        props.logOutUser(() => {
            setToggleLogOut(false)
        })
    }


.
.
.
.
.
.
.
.


function mapStateToProps (state) {
    return {
        user: state.user.userData
    }
}

export default connect(mapStateToProps)(Header)                                                                                                     

(Unhandled Rejection (TypeError): Cannot read property 'isAuth' of undefined) https://prnt.sc/tkd0bj

Can
  • 1
  • 2
  • I think you need to learn more about how redux works. Where is your reducers. Did you update your reducers. If so use this https://react-redux.js.org/api/hooks#useselector – Monzoor Tamal Jul 18 '20 at 20:47
  • https://prnt.sc/tkdkzo this is how my reducer looks like. After firing dispatch in Header component I get this error but in redux dev-tools I can see that dispatch is completed. So .then() does not work here. https://prnt.sc/tkdklb – Can Jul 18 '20 at 20:58
  • I converted to useSelector so thats why in this one I dont have props.user but user* – Can Jul 18 '20 at 21:01
  • I call authUser action in the Header and in protected routes at the same time for every route. Is that the issue ? – Can Jul 18 '20 at 21:06
0

problem1: The problem is in your axios call. enter link description here read the documentation. axios get returns a promise. use can use try catch or async await.

problem2:

const authData = useSelector(state => state.user)
const [isLoading, setIsLoading] = useState(true)

useEffect(() => {
   if(authData.isAuth) {
      setIsLoading(false)
   }

}, [authData]);

if(isLoading) return <p>loading...</p>

// your rest of code
Monzoor Tamal
  • 790
  • 5
  • 15
  • Since first value of isAuth is undefined, It will always cause error. we should somehow delay before reaching condition part but .then() does not work. It can be solved with callback inside of action creator but whats the point then. There is something really weird about middlewares(thunk, promise) – Can Jul 18 '20 at 21:52
  • create a sand box code. will see the main issue on there – Monzoor Tamal Jul 18 '20 at 22:04