-3

i'm using axios in redux. And i wonder here is my api call with axios. It's synchronous working? if not how i can do it synchronous?

return (dispatch) => {
  dispatch({
    type: FETCH_ALLDRIVER_DATA_START
  })

  return axios.post(baseUrl + 'v1/drivers/alldriver', {
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      }
    })
    .then(response => {
      console.log('jj')
      console.log(response)
    })
    .catch(error => {
      throw (error);
    });
};
t.niese
  • 39,256
  • 9
  • 74
  • 101
user3348410
  • 2,733
  • 10
  • 51
  • 85
  • yes it is synchronous as per your code. What problem you are facing? – Vikas Kumar May 07 '19 at 06:38
  • API calls are designed to be async. – Agney May 07 '19 at 06:39
  • The call is async, which means you're returning a pending Promise. If you want to return the result instead, you have to make the function `async` and inside, use `await` to wait for the Promise to resolve/reject. Basically: `return await axios.post(...)...;` –  May 07 '19 at 06:48
  • i don't want make async so i wan't to make when function calling will wait the response while making something another. Because my components rendering without waiting the response often – user3348410 May 07 '19 at 06:51
  • @VikasKumar `axios.post` does not return the result in a synchronous way. The code is executed in order because Promise chaining is used. – t.niese May 07 '19 at 06:56
  • Do you need to wait the response from the API before dispatching the action? If so, you could try call `dispatch` in the promise resolve (`then` callback) – Francisco Hanna May 07 '19 at 06:57
  • @user3348410 `Because my components rendering without waiting the response often` then you need to fix this, making the `axios` sync would be a workaround, but not a correct way to solve the actual problem. – t.niese May 07 '19 at 06:58
  • @t.niese thats what I wanted to say. so I added 'as per code'. – Vikas Kumar May 08 '19 at 07:02

2 Answers2

0

axios.post(...).then(...) is a promise which is async. With axios I think you cannot really make it synchronous: How to make axios synchronous

Ideally with redux I would use redux-thunk to make async calls.

Synchronous calls will make the main thread pause (making the entire page unresponsive) until response is received (imagine clients on slow connections) which is bad user experience. I am not sure why you want to make it synchronous, but if you really should, try using XMLHttpRequest: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Synchronous_and_Asynchronous_Requests#Synchronous_request

tejasbubane
  • 914
  • 1
  • 8
  • 11
  • I need it because my components are sometimes rendering without waiting the response from api. – user3348410 May 07 '19 at 06:53
  • 1
    Components will eventually `re-render` when data is received (props change) - this is normal. You could add some wait indicator like spinner during that time if you don't want to show blank component. – tejasbubane May 07 '19 at 06:55
  • See my edited answer as to why it is a bad practice to make it synchronous. – tejasbubane May 07 '19 at 06:57
0

If you need the request to be over before calling the dispatch function, you could call it in the promise resolve callback (then), as follows:

return (dispatch) => {
    return axios.post(baseUrl + 'v1/drivers/alldriver', {
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      }
    })
    .then(response => {
      console.log('jj')
      console.log(response)
      // here call whatever you want to do after a succesful request
      dispatch({
          type: FETCH_ALLDRIVER_DATA_START
      })
    })
    .catch(error => {
      throw (error);
    });
};

Bear in mind that this is still an async call, but with code beign executed after the request ended successfully.

If you really want to make a sync call, use async and await like so:

return async (dispatch) => {
    const response = await axios.post(baseUrl + 'v1/drivers/alldriver', {
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      }
    });

    dispatch({
        type: FETCH_ALLDRIVER_DATA_START
    })
};

Altough I dont't knoe how redux will behave with a sync call.

I'm not sure what you are trying to achieve and why you would need the request call to be syncrhonous. If your components are rendering without data, or something like that, the solution must be somewhere else and not in this call.

Hope it helps.

Francisco Hanna
  • 1,137
  • 1
  • 11
  • 27