Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

extract both JSON and headers from fetch()

I am modelling the auth layer for a simple react/redux app. On the server side I have an API based on the devise_token_auth gem.

I am using fetch to post a sign in request:

const JSON_HEADERS = new Headers({
  'Content-Type': 'application/json'
});

export const postLogin = ({ email, password }) => fetch(
  `${API_ROOT}/v1/auth/sign_in`, {
    method: 'POST',
    headers: JSON_HEADERS,
    body: JSON.stringify({ email, password })
});

// postLogin({ email: '[email protected]', password: 'whatever' });

This works, and I get a 200 response and all the data I need. My problem is, information is divided between the response body and headers.

  • Body: user info
  • Headers: access-token, expiration, etc.

I could parse the JSON body this way:

postLogin({ '[email protected]', password: 'whatever' })
  .then(res => res.json())
  .then(resJson => dispatch(myAction(resJson))

But then myAction would not get any data from the headers (lost while parsing JSON).

Is there a way to get both headers and body from a fetch Request? Thanks!

like image 511
nerfologist Avatar asked Dec 23 '22 21:12

nerfologist


1 Answers

I thought I'd share the way we finally solved this problem: by just adding a step in the .then chain (before parsing the JSON) to parse the auth headers and dispatch the proper action:

fetch('/some/url')
  .then(res => {
    const authHeaders = ['access-token', 'client', 'uid']
      .reduce((result, key) => {
        let val = res.headers.get(key);
        if (val) {
          result[key] = val;
        }
      }, {});
    store.dispatch(doSomethingWith(authHeaders)); // or localStorage
    return res;
  })
  .then(res => res.json())
  .then(jsonResponse => doSomethingElseWith(jsonResponse))

One more approach, inspired by the mighty Dan Abramov (http://stackoverflow.com/a/37099629/1463770)

fetch('/some/url')
  .then(res => res.json().then(json => ({
    headers: res.headers,
    status: res.status,
    json
  }))
.then({ headers, status, json } => goCrazyWith(headers, status, json));

HTH

like image 127
nerfologist Avatar answered Dec 26 '22 12:12

nerfologist