Reputation: 2654
I am not sure how to handle errors of api request in a reducer using redux.
i have the following in my reducer
export default function(state = {}, action) {
switch (action.type) {
case APPROVE_COMMSMATRIX_SOX:
case FETCH_COMMSMATRIX:
if (action.payload.data.header.error) {
return Object.assign({}, state, {
error: {
code: "INVALID ACTION",
message: action.payload.data.header.message,
action
}
});
} else {
return { ...state, [action.payload.data.body.recordset.record[0].id] : action.payload.data.body.recordset.record[0] };
}
default:
return state;
}
}
My api call is returning a valid error but how can i display this to the user? This is how i have it in my component to handle reducer errors. i am checking if error exists in the state object that is returned by the reducer and rendering the message onto the page by setting the state
class Approve extends Component {
constructor(props) {
super(props);
this.runOnce = false;
this.initConfirm = this.initConfirm.bind(this);
this.state = {
message : <div>Confirming...<i className="fa fa-spinner fa-spin"></i></div>
}
}
componentDidMount() {
const id = this.props.match.params.id;
this.props.approveCommsmatrixSox(id);
}
initConfirm(){
this.runOnce = true;
if(this.props.approvecommsmatrix.error){
this.setState({ message: this.props.approvecommsmatrix.error.message});
}
}
render() {
const { approvecommsmatrix } = this.props ;
if(!this.runOnce && approvecommsmatrix !== undefined && Object.keys(approvecommsmatrix).length > 0 ){
this.initConfirm();
}
return (
<div className="container-fluid">
<div className="row-fluid top-buffer">{this.state.message}</div>
</div>
);
}
}
function mapStateToProps({ commsmatrices }, ownProps) {
if(commsmatrices.error){
return { approvecommsmatrix : commsmatrices };
}
return { approvecommsmatrix : commsmatrices[ownProps.match.params.id] };
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(
{ approveCommsmatrixSox },
dispatch
);
}
export default connect(mapStateToProps, { approveCommsmatrixSox })(Approve);
UPDATE
i have updated the component to display error message and returning the error in the reducer.
initConfirm(){
this.runOnce = true;
if(this.props.approvecommsmatrix.error){
this.setState({ message: this.props.approvecommsmatrix.error.message});
}else{
}
}
In my reducer i do not understand how to call another error case
as you mentioned in answer.
actions
import axios from 'axios';
export const FETCH_COMMSMATRIX = 'fetch_commsmatrix';
export function fetchCommsmatrix(id) {
const request = axios.get(`/api/user/comms/matrices/id/`+id+`/format/json?quiet=1`);
return {
type: FETCH_COMMSMATRIX,
payload: request
};
}
export const FETCH_COMMSMATRICES_BY_SERVICE = 'fetch_commsmatrices_by_service';
export function fetchCommsmatricesByService(service_id) {
const request = axios.get(`/api/user/comms/matrices/format/json?quiet=1&service_id=`+service_id);
return {
type: FETCH_COMMSMATRICES_BY_SERVICE,
payload: request
};
}
export const APPROVE_COMMSMATRIX_SOX = 'approve_commsmatrix_sox';
export function approveCommsmatrixSox(id) {
const params = 'approve=1';
const request = axios.post(`/api/admin/rename/comms/matrices/id/`+id+`/format/json?quiet=1`,params);
return {
type: APPROVE_COMMSMATRIX_SOX,
payload: request
};
}
Upvotes: 0
Views: 6069
Reputation: 2647
What I would do in this situation is to add an error variable to the state, and create another action for this error.
In your reducer
case ERROR:
return {
...state,
error: action.error
}
in your app's render function you check this error before your main return.
if(this.props.error)
return (
<div className="container-fluid">
{this.props.error}
</div>
);
In your action, you simply check for error, and return an ERROR action when it exist. Maybe something like this.
let returnValue;
if(request.data.header.error !== null) {
returnValue = {type: ERROR,payload: request.data.header.error}
} else {
returnValue = {
type: FETCH_COMMSMATRIX,
payload: request
};
}
return returnValue;
Upvotes: 3