Return fetch.json inside the object.

I have an API call function that I would like to return in the response.json () file as well as response.status together in one object.

Same:

  const getData = data => {
  return fetch('/api_endpoint',{
      method: 'GET',
      headers: {
          'Content-type': 'application/json'
      }
  })
  .then(response => {
        return { 
                  body: response.json(), 
                  status: response.status 
               }
    })
}

The problem is that response.json () is a promise, so I cannot pull out its value until it is resolved.

I can crack it by doing this:

  const getData = data => {
  let statusRes = undefined;
  return fetch('/api_endpoint',{
      method: 'GET',
      headers: {
          'Content-type': 'application/json'
      }
  })
  .then(response => {
        statusRes = response.status;
        return response.json()
    })
  .then(data => {
      return {
          body: data,
          status: statusRes
      }
    }
  )
}

But this is simply WRONG. Anyone have a better idea?

0
source share
3 answers
const getData = data => {
  return fetch('/api_endpoint',{
      method: 'GET',
      headers: {
          'Content-type': 'application/json'
      }
  })
  .then(async response => {
        return { 
                  body: await response.json(), 
                  status: response.status 
               }
    })
}

ES6 async / wait can help it look cleaner

+1
source

There is no need for a variable, if it bothers you, you can return tuples (array in ES).

, .

const getData = data => {
  return fetch('/api_endpoint',{
      method: 'GET',
      headers: {
          'Content-type': 'application/json'
      }
  })
  .then(response =>
    //promise all can receive non promise values
    Promise.all([//resolve to a "tuple"
      response.status,
      response.json()
    ])
  )
  .then(
    /**use deconstruct**/([status,body]) =>
    //object literal syntax is confused with
    //  function body if not wrapped in parentheses
      ({
          body,
          status
      })
  )
}

, :

const getData = data => {
  return fetch('/api_endpoint',{
      method: 'GET',
      headers: {
          'Content-type': 'application/json'
      }
  })
  .then(response =>
      response.json()
      .then(
        body=>({
          body,
          status:response.status
        })
      )
  )
}

, await , . , , , , .

, json , json - , body/status, .

:

typeof JSON.parse(JSON.stringify({startDate:new Date()})).startDate//is string

, , :

  • URL-
  • , /.

, url - a b .. .. :

a -> b -> c -> d ; [b,d]-> e

, a -> e, 4 :

  • a -> b
  • b -> c
  • c -> d
  • [b,d] -> e

1 2 2 3 1.then(2).then(3) , 2 , 4.

, - a -> e, c -> d ( ) , [b,d] -> e .

( , , ). (a, b, c, d, e) , a b, b c... a-c a b b c, , [b,d] e

objectAndResponseToObjectAndStatusObject, ( 1- ) ( 3- ) thread, createThread.

//this goes into a library of utility functions
const promiseLike = val =>
  (val&&typeof val.then === "function");
const REPLACE = {};
const SAVE = {}
const createThread = (saved=[]) => (fn,action) => arg =>{
  const processResult = result =>{
    const addAndReturn = result => {
      (action===SAVE)?saved = saved.concat([result]):false;
      (action===REPLACE)?saved = [result]:false;
      return result;  
    };
    return (promiseLike(result))
      ? result.then(addAndReturn)
      : addAndReturn(result)
  }
  return (promiseLike(arg))
    ? arg.then(
        result=>
          fn(saved.concat([result]))
      )
      .then(processResult)
    : processResult(fn(saved.concat([arg])))
};
const jsonWithActualDates = keyIsDate => object => {
  const recur = object =>
    Object.assign(
      {},
      object,
      Object.keys(object).reduce(
        (o,key)=>{
          (object[key]&&(typeof object[key] === "object"))
            ? o[key] = recur(object[key])
            : (keyIsDate(key))
                ? o[key] = new Date(object[key])
                : o[key] = object[key];
          return o;
        },
        {}
      )
    );
  return recur(object);
}

const testJSON = JSON.stringify({
  startDate:new Date(),
  other:"some other value",
  range:{
    min:new Date(Date.now()-100000),
    max:new Date(Date.now()+100000),
    other:22
  }
});

//library of application specific implementation (type a to b)
const urlToResponse = url => //a -> b
  Promise.resolve({
    status:200,
    json:()=>JSON.parse(testJSON)
  });
const responseToObject = response => response.json();//b -> c
const objectWithDates = object =>//c -> d
  jsonWithActualDates
    (x=>x.toLowerCase().indexOf("date")!==-1||x==="min"||x==="max")
    (object);
const objectAndResponseToObjectAndStatusObject = ([response,object]) =>//d -> e
  ({
    body:object,
    status:response.status
  });

//actual work flow
const getData = (url) => {
  const thread = createThread();
  return Promise.resolve(url)
  .then( thread(urlToResponse,SAVE) )//save the response
  .then( responseToObject )//does not use threaded value
  .then( objectWithDates )//does no use threaded value
  .then( thread(objectAndResponseToObjectAndStatusObject) )//uses threaded value
};
getData("some url")
.then(
  results=>console.log(results)
);
Hide result

getData :

const getData = async (url) => {
  const response = await urlToResponse(url);
  const data = await responseToObject(response);
  const dataWithDates = objectWithDates(data);
  return objectAndResponseToObjectAndStatusObject([response,dataWithDates]);
};

: getData ? , getData , , url , ... GetData .

getData, , , :

const getData = (url) => 
  urlToResponse(url).then(
    response=>
      responseToObject(response)
      .then(objectWithDates)
      .then(o=>objectAndResponseToObjectAndStatusObject([response,o]))
  );

, , getDate.

( compose ) . , , , .

, , . ( ), 1 , , .

:

const getDataFunctions = [
  [pipe([setPage,setFiler]),SET_PARAMS],
  [makeRequest,MAKE_REQUEST],
  [setResult,SET_RESULTS],
];

. :

const initialLoad = (action,state) =>
  pipe(getDataFunctions.map(([fn])=>fn))([action,state]);

:

const pageChanged = action =>
  pipe(getDataFunctions.map(
    ([fn,type])=>{
      if(type===SET_PARAMS){
        return setPage
      }
      return fn;
    }
  ))([action,state]);
const filterChanged = action =>
  pipe(getDataFunctions.map(
    ([fn,type])=>{
      if(type===SET_PARAMS){
        return setFiler
      }
      return fn;
    }
  ))([action,state]);

, , , . InitialLoad , ( ), pageChanged , , , filterChanges , .

, , , ?

const getDataFunctions = [
  [pipe([setPage,setFiler]),SET_PARAMS],
  [fromCache(makeRequest),CACHE_OR_REQUEST],
  [setResult,SET_RESULTS],
];

getData pipe thread ( , ).

const getData = url => {
  const thread = createThread();
  return pipe([//array of functions, can be defined somewhere else or passed in
    thread(urlToResponse,SAVE),//save the response
    responseToObject,
    objectWithDates,
    thread(objectAndResponseToObjectAndStatusObject)//uses threaded value
  ])(url);
};

JavaScript, , T->T, , , threaded go a b c.

- F # ReasonML, , , .

0

async/await. :

async function getData(endpoint) {
  const res = await fetch(endpoint, {
    method: 'GET'
  })

  const body = await res.json()

  return {
    status: res.status,
    body
  }
}

try / catch res.ok, 20x.

0

Source: https://habr.com/ru/post/1693458/


All Articles