Reputation: 1315
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
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
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