Reputation: 147
I can't figure how to make a post request with axios and redux-thunk so the action is dispatched after the query.
Here's my request module
export default {
get: function (action, url) {
return (dispatch) => {
axios.get(`${ROOT_URL}${url}`)
.then(({ data }) => {
dispatch({
type: action,
payload: data
});
});
};
},
post: function (action, url, props) {
return (dispatch) => {
axios.post(`${ROOT_URL}${url}`, props)
.then(({ data }) => {
return (dispatch) => {
dispatch({
type: action,
payload: data
});
};
});
};
}
}
The GET works. When I call the post function, it enters the function, but never run the returned function.
I tried modifying the order of the functions. I ended up with a working post request, but the action was never dispatched.
post: function (action, url, props) {
//POST works but action is not dispatched to reducer
axios.post(`${ROOT_URL}${url}`, props)
.then(({ data }) => {
return (dispatch) => {
dispatch({
type: action,
payload: data
});
};
});
}
Any idea how I can achieve a working post request that gets send to my api and then the response is dispatched to the reducer?
Thank you!
After extensive testing and back and forth, I think the problem is in redux-form. As pointed by Michael, the dispatch should work. I tested my call in my component with the get method and it doesn't work. Here's my component
const form = reduxForm({
form: 'LoginPage',
validate
});
const renderField = ({ input, label, type, meta: { touched, error } }) => (
<div className="form-group">
<label>{label}</label>
<div>
<input {...input} placeholder={label} type={type} className="form-control" />
{touched && ((error && <span>{error}</span>))}
</div>
</div>
)
class LoginPage extends Component {
displayName: 'LoginPage';
onSubmit(props) {
login(props.email, props.password);
}
render() {
const {handleSubmit} = this.props;
return (
<div className='row'>
<div className='center-block'>
<form onSubmit={handleSubmit(this.onSubmit.bind(this))}>
<Field name="email" type="email" label='Courriel :' component={renderField} />
<Field name="password" type="password" label='Mot de passe :' component={renderField} />
<div className="form-group text-center">
<button type="submit" className='btn btn-primary'>Se connecter</button>
</div>
</form >
</div>
</div>
);
};
};
const validate = values => {
const errors = {}
if (!values.email) {
errors.email = 'Required'
} else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)) {
errors.email = 'Invalid email address'
}
if (!values.password) {
errors.password = 'Required'
} 4
return errors
}
export default reduxForm({
form: 'LoginPage',
validate
})(LoginPage);
The post request is in the onSubmit method. The login method is called but the return value is never dispatched.
Again, thank you for your time and help
Upvotes: 2
Views: 10138
Reputation: 143
Can't add a comment, but I'm glad you figured it out. I'd like to warn you however that on newer versions of redux-form you'll have to decorate your form outside of the connect function to redux. I ran into this problem and it drove me nuts trying to figure it out.
it would be a two step process to connect redux-form after the update. for example, it would look like this.
LoginPage = reduxForm({form: 'LoginPage', validate})(LoginPage)
and then afterwards your standard connect function
export default connect(null, actions)(LoginPage)
hope this saves you the headache in the future
Upvotes: 2
Reputation: 147
I found my problem. Thanks to Michael for his comment that helped me look in another direction.
The problem was that my form wasn't connected to redux. I ended up adding the connect function to my export statement.
export default connect(null, { login })
(reduxForm({
form: 'LoginPage',
validate
})(LoginPage));
And I also had to change the call to the login function in onSubmit
onSubmit(props) {
this.props.login(props.email, props.password);
}
Upvotes: 4
Reputation: 143
your function shouldnt 'return (dispatch)' again, because what the action does is return a function. it should just be
function myFunc(action, url) {
return function (dispatch) {
axios.post(`${ROOT_URL}${url}`, props)
.then(response => {
dispatch({
type: action,
payload: response.data
})
})
}
}
edited with full function.
Upvotes: 0