TaouBen
TaouBen

Reputation: 1315

How to get data from my axios request without using a setTimeout?

I am having a problem, I believe many of you have faced it somehow, so I am using axios to get my data :

 let data = axios.get(
    "http://localhost:8080/api/taskExecution?&search=&page=1&size=8"
  ).then(response => {
    if (response.status !== 200) {
      console.log("LOADING");
    } else {
      return response.data;
    }
  });
  let tasks = [];

  data.then(response => {
    tasks = response;
  });

  console.log(tasks);

  return tasks;

Something like this, response data returns array of 8 items, but tasks is still empty which is normal because the axios request takes some time, I can use setTimeout for 100ms and inside it, I put console.log(tasks); and it will work but is not a proper solution, because what if the server takes 5s to returns the data?

This code is in my reducer, so I have to get my tasks and return them so I can display them, and show a loader when the request is executed.

This is my reducer :

import update from "immutability-helper";
import Axios from "axios";

export default function getTasksReducer(state = [], action) {
  switch (action.type) {
    case "GET_TASKS":
      let data = Axios.get(
        "http://localhost:8080/api/taskExecution?&search=&page=1&size=8"
      ).then(response => {
        if (response.status !== 200) {
          console.log("LOADING");
        } else {
          return response.data;
        }
      });
      let tasks = [];

      data.then(response => {
        tasks = response;
      });

      console.log(tasks);

      return tasks;
    default:
      return state;
  }
}

I need some help in this code and also in the conception of it, I mean where should I change my loader state and so forth.

Upvotes: 0

Views: 361

Answers (2)

Firealem Erko
Firealem Erko

Reputation: 357

As mentiond as in the other answers, I would setup my reducer only to handle state update and the action creator function to fetch data. Here is the minimal starting point if I were to do it. you can use the loading state to display loading spinners or progress bars.

my action creator function with the individual actions:

export const GET_TASKS_START = "GET_TASKS";
export const GET_TASKS_SUCCESS = "GET_TASKS_SUCCESS";
export const GET_TASKS_FAILURE = "GET_TASKS_FAILURE";

export const getData = () => dispatch => {
  dispatch(GET_TASKS_START);
  axios
    .get("http://localhost:8080/api/taskExecution?&search=&page=1&size=8")
    .then(response => {
      dispatch({ type: GET_TASKS_SUCESS, payload: response.data });
    })
    .catch(err => {
      dispatch({ type: GET_TASKS_FAILURE, payload: err.response });
    });
};

and the reducer would handle the state update as follows:

import {
  GET_TASKS_SUCCESS,
  GET_TASKS_FAILURE,
  GET_TASKS_START
} from "./Action.js";

const initialState = {
  tasks: [],
  error: null,
  loading: false
};
export default function tasksReducer(state = initialState, action) {
  switch (action.type) {
    case GET_TASKS_START:
      return {
        ...state,
        loading: true
      };
    case GET_TASKS_SUCCESS:
      return {
        ...state,
        loading: false,
        tasks: action.payload, 
        error: null
      };
    case GET_TASKS_FAILURE:
      return {
        ...state,
        loading: false,
        error: action.payload
      };
  }
}

I would suggest console logging and checking the responses (data and errors ) and modify the two functions accordingly

Upvotes: 0

Subin Sebastian
Subin Sebastian

Reputation: 10997

I guess you can spent some time in understanding Promises and async/awiat

For eg: if you do this, your console will have all tasks listed.

 data.then(response => {
   tasks = response;
   console.log(tasks);
 });

Reason for that is the function you are passing to .then function of a promise is not executed immediately, its executed once a Promise is resolved(In your case after finishing execution of the http request.)

To get a more line by line execution feel you can use async/await

  let tasks = await Axios.get("http://localhost:8080/api/taskExecution?&search=&page=1&size=8")
    .then(response => {
      if (response.status !== 200) {
         console.log("LOADING");
      } else {
         return response.data;
      }
    });
    console.log(tasks);
    return tasks;

The catch is that you can use await only inside an async function https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

Upvotes: 1

Related Questions