During implementing login feature with React, Redux, isomorphic-fetch, ES6 Babel.
Questions
I do not know how to properly bine promises after the checkstatus promise in order to get parsed JSON data from my server.
what am I doing wrong here?
also, do I need to replace isomorphic-fetch
package with other more convenient one?
any suggestion for other package is wele!
loginAction.js
import * as API from '../middleware/api';
import * as ActionTypes from '../actionTypes/authActionTypes';
import 'isomorphic-fetch';
function encodeCredentials(id, pwd) {
return btoa(`${id}{GS}${pwd}`);
}
function checkStatus(response) {
if (response.status >= 200 && response.status < 300) {
response;
} else {
const error = new Error(response.statusText);
error.response = response;
throw error;
}
}
function parseJSON(response) {
return response.json();
}
export function loginFailure(error) {
return { error, type: ActionTypes.LOGIN_FAILURE };
}
export function loginSuccess(response) {
return dispatch => {
dispatch({ response, type: ActionTypes.LOGIN_SUCCESS });
};
}
export function loginRequest(id, pwd) {
return {
type: ActionTypes.LOGIN_REQUEST,
mand: 'login',
lang: 'en',
str: encodeCredentials(id, pwd),
ip: '',
device_id: '',
install_ver: '',
};
}
export function login(id, pwd) {
const credentials = loginRequest(id, pwd);
return dispatch => {
fetch(`${API.ROOT_PATH}${API.END_POINT.LOGIN}`, {
method: 'post',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(credentials),
})
.then(checkStatus)
.then(parseJSON)
.then(data => {
console.log(`parsed data ${data}`);
dispatch(loginSuccess(data));
})
.catch(error => {
console.log(`request failed ${error}`);
});
};
}
During implementing login feature with React, Redux, isomorphic-fetch, ES6 Babel.
Questions
I do not know how to properly bine promises after the checkstatus promise in order to get parsed JSON data from my server.
what am I doing wrong here?
also, do I need to replace isomorphic-fetch
package with other more convenient one?
any suggestion for other package is wele!
loginAction.js
import * as API from '../middleware/api';
import * as ActionTypes from '../actionTypes/authActionTypes';
import 'isomorphic-fetch';
function encodeCredentials(id, pwd) {
return btoa(`${id}{GS}${pwd}`);
}
function checkStatus(response) {
if (response.status >= 200 && response.status < 300) {
response;
} else {
const error = new Error(response.statusText);
error.response = response;
throw error;
}
}
function parseJSON(response) {
return response.json();
}
export function loginFailure(error) {
return { error, type: ActionTypes.LOGIN_FAILURE };
}
export function loginSuccess(response) {
return dispatch => {
dispatch({ response, type: ActionTypes.LOGIN_SUCCESS });
};
}
export function loginRequest(id, pwd) {
return {
type: ActionTypes.LOGIN_REQUEST,
mand: 'login',
lang: 'en',
str: encodeCredentials(id, pwd),
ip: '',
device_id: '',
install_ver: '',
};
}
export function login(id, pwd) {
const credentials = loginRequest(id, pwd);
return dispatch => {
fetch(`${API.ROOT_PATH}${API.END_POINT.LOGIN}`, {
method: 'post',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(credentials),
})
.then(checkStatus)
.then(parseJSON)
.then(data => {
console.log(`parsed data ${data}`);
dispatch(loginSuccess(data));
})
.catch(error => {
console.log(`request failed ${error}`);
});
};
}
Share
Improve this question
asked Jan 13, 2016 at 17:06
seoyoochanseoyoochan
8423 gold badges15 silver badges28 bronze badges
2 Answers
Reset to default 9In my projects usually, I have a helper function fetchJSON
that does all utility logic, such as JSON parsing and status check.
Here it is:
import fetch from 'isomorphic-fetch';
function checkStatus(response) {
if(response.ok) {
return response;
} else {
const error = new Error(response.statusText);
error.response = response;
throw error;
}
}
function parseJSON(response) {
return response.json();
}
export default function enhancedFetch(url, options) {
options.headers = Object.assign({
'Accept': 'application/json',
'Content-Type': 'application/json'
}, options.headers);
if(typeof options.body !== 'string') {
options.body = JSON.stringify(options.body);
}
return fetch(url, options)
.then(checkStatus)
.then(parseJSON);
}
Then you can use it in actions:
import fetchJSON from '../utils/fetchJSON'; // this is the enhanced method from utilities
export function login(id, pwd) {
const credentials = loginRequest(id, pwd);
return dispatch => {
fetchJSON(`${API.ROOT_PATH}${API.END_POINT.LOGIN}`, {
method: 'post',
body: credentials
}).then(data => {
console.log(`parsed data ${data}`);
dispatch(loginSuccess(data));
}).catch(error => {
console.log(`request failed ${error}`);
});
};
}
It helps you to keep actions code clean from some boilerplate code. In big projects with tons of similar fetch
calls it is a really must-have thing.
You're doing it right, you just forgot return
in checkstatus
; you should return the response
such that the next promise in the chain can consume it.
Also, it seems that checkstatus
is synchronous operation, so it's no need to chain it by .then
(although, it's OK if you like it that way), you can write:
fetch(...)
.then(response=>{
checkStatus(response)
return response.json()
})
.then(data=>{
dispatch(loginSuccess(data))
})
.catch(...)
I see no reason to get rid of isomorphic-fetch
for now - it seems that it does its job.