Vuex action not waiting to finish axios promise - javascript

I encounter a strange situation developing an application in Laravel + VueJS/Vuex stack.
I understand that if a promise is not returned the parent function calling it will not wait for it to resolve so things will go asynchronous. Axios returns a promise by default when calling a resourse through http.
So i have the parent function which looks like this:
fetchInvoiceSeries() {
var arr = []
let invsrs = this.$store.getters['getInvoiceSeries']
if (invsrs == null) {
return this.$store
.dispatch('get_invoice_series')
.then(() => {
invsrs = this.$store.getters['getInvoiceSeries']
if (invsrs != null) {
invsrs.forEach(function(s) {
arr.push({
value: s.id,
text: s.series + ' / ' + s.increment
})
})
this.series = arr
} else {
console.log('Error while fetching invoice series!')
}
})
.catch(e => {
console.log(e)
})
} else {
invsrs.forEach(function(s) {
arr.push({
value: s.id,
text: s.series + ' / ' + s.increment
})
})
this.series = arr
}
}
And here is the function defined in action part of the vuex module:
get_invoice_series({ commit }) {
return get('/api/series/0')
.then(response => {
if (response.data && typeof response.data !== undefined) {
let payload = response.data
commit('SET_INVOICE_SERIES', payload)
} else {
console.log('error', error)
}
})
.catch(error => {
console.log('error', error)
})
},
So as you can see i am returning the get request from axios inside the action. In the parent i am calling the action and the "then" keyword in order to do some processing after the action it's done. Also i am using arrow function because i need the context in the parent function in order to call this.$store ...
The problem is that even after checking the getter to see if the state have the invoice series and getting them using the get_invoice_series action i still don't have the invoice series in memory judging by the code i wrote. The console keeps loggin 'Error while fetching invoice series!' the first time i execute the code and the second time (after the information exists in state), the code skips fetching the invoice series (as expected).
Can you tell me what i am doing wrong ? Thank you!

Your error comes from invsrs being null the first time, and not null the second time.
This means that your function get_invoice_series({ commit }) is asynchronous, and that it returns a promise.
For more readability, maybe you should make your call independently from your return statement, using async/await expressions :
async get_invoice_series({ commit }) {
const response = await get('/api/series/0')
if (response.data === undefined) return null
const payload = response.data
commit('SET_INVOICE_SERIES', payload)
return payload
},
And then make your calls wait for this fetch to process :
async fetchInvoiceSeries() {
let arr = []
const invsrs = await this.$store.getters['getInvoiceSeries']
// ...
It's pure conjecture here, let me know if it helps or not.

Related

Is it possible to call to APIs inside a react-router loader function

I'd like to know if it's possible to make 2 API calls inside a loader function if I am using react-router 6. My ideas was to create an object based on these 2 calls and destruct the object in the rendering component like this:
function MainComponent (){
const {data , reservation} = useRouteLoaderData('room-details');
..
..
}
export default MainComponent;
export async function loader({request, params}) {
const id = params.roomId;
const response = await fetch ('http://localhost:8080/rooms/' + id);
const response2 = await fetch('http://localhost:8080/rooms/reservation/' + id)
const megaResponse = {
data: response, //i tried data:{respose} It ain't work
reservation: response2,
};
if (!response.ok) {
throw json({message: 'Something Wrong'}, {status: 500});
}
else {
return megaResponse;
}
}
But i have no success output.
I'd really want to make these 2 call in one place, otherwise I will have to use useEffect in a child component. Not a good Idea I think.
Thanks
I suspect you are not returning the unpacked response, i.e. JSON. I suggest surrounding the asynchronous code in a try/catch and simply try to process the requests/responses. Unpack the JSON value from the response objects. Since it doesn't appear the requests are dependent on one another I recommend loading them into an array of Promises that can be run concurrently and awaited as a whole. If during any part of the processing a Promise is rejected or an exception thrown, the catch block will return the JSON error response to the UI, otherwise, the { data, reservation } object is returned.
const loader = async ({ request, params }) => {
const { roomId } = params;
try {
const [data, reservation] = await Promise.all([
fetch("http://localhost:8080/rooms/" + roomId),
fetch("http://localhost:8080/rooms/reservaton/" + roomId)
]).then((responses) => responses.map((response) => response.json()));
return { data, reservation };
} catch {
throw json({ message: "Something Wrong" }, { status: 500 });
}
};
I found the solution, I tried it and it worked. It is as follow:
function MainComponent (){
const [data , reservation] = useRouteLoaderData('room-details');
..
..
}
export default MainComponent;
export async function loader({request, params}) {
const id = params.roomId;
return Promise.all([
fetch ('http://localhost:8080/rooms/' + id),
fetch('http://localhost:8080/rooms/reservation/' + id)
])
.then(
([data, reservation]) =>
Promise.all([data.json(), reservation.json()]),
error => {throw json({message: 'Something Wrong'}, {status: 500});}
)
.then(([data, reservation]) => {
return [data, reservation];
});
}
Thanks

Cannot read property 'code' of undefined from promise, context api (react hook)

I am making my first hybrid web app using react hook.
I am faced with a timing problem with promise and context api.
Here are the logic I am facing with.
A function fetchApplications gets data from firebase firestore, it is defined in globalcontext.js (called in tableView)
tableView.js calls fetchApplications in useEffect.
fetchApplications is defined as promise function, I expect it will resolve(return) data until data fetched, it will resolove(return) object like {code:200, data:data}
problem
in the fetchData.code,
Cannot read property 'code' of undefined
Here is my code
In the tableview.js
React.useEffect(() => {
context.fetchApplications(auth.userId, "")
.then(function (fetchData) {
console.log("Fetched data: ", fetchData); ///this is undefined
if (fetchData.code !== 200) { /// error part
alert(fetchData.msg);
}
if (!fetchData.data) {
alert("No applications");
}
setsData(fetchData.data);
});
}, []);
In the GlobalContext.js
async function fetchApplications(userId, role) {
return new Promise((resolve, reject) => {
// resolve({ code: 200, data: "data" }); //If I add this code, it will be alright.
let dataArray = [];
let applicationRef = db
.collection("Users")
.doc(userId)
.collection("Applications");
applicationRef
.get()
.then(function (qs) {
qs.forEach(function (doc) { //doesn't work
console.log(doc.id, " => ", doc.data());
console.log(doc.size, " => ", typeof doc);
dataArray.push(doc.data());
});
return Promise.resolve(dataArray);
})
.then((data) => {
console.log("Global, Fetched Data", dataArray);
if (data) {
resolve({ code: 200, data: data });
}
return;
});
}).catch(function (error) {
reject({ code: 400, msg: "시스템에러 고객센터에 문의해주세요" });
});
}
wrote in codesendbox
If I was write the wrong way of promise, please let me know.
thanks
You're implementing a couple of bad practices and have some major issues. For starters, fetchApplications is marked as async but you're returning a manually created promise which is quite overkill as your fetching code actually generates a promise which you should directly return. Furthermore:
.then(function (qs) {
qs.forEach(function (doc) { //doesn't work
console.log(doc.id, " => ", doc.data());
console.log(doc.size, " => ", typeof doc);
dataArray.push(doc.data());
});
return Promise.resolve(dataArray);
})
I am not sure what exactly "//doesn't work" should mean but return Promise.resolve(dataArray); won't cut it for you. You're already in the then chain, so you can't resolve anything from the main promise at this point. You should just pass the data to the next then callback as return dataArray;.
All in all, I will suggest ditching the then-ables syntax all together and migrate to async/await altogether:
async function fetchApplications(userId, role) {
try {
const dataArray = [];
const applicationRef = db
.collection("Users")
.doc(userId)
.collection("Applications");
const querySnapshot = await applicationRef.get();
querySnapshot.forEach(doc => {
dataArray.push(doc.data());
});
return {
code: 200,
data: dataArray
};
}
catch (error) {
return {
code: 400,
msg: '시스템에러 고객센터에 문의해주세요'
};
}
}
Then, in your react component/hook:
React.useEffect(() => {
const fetchApplicationDataAsync = async () => {
const result = await context.fetchApplications(auth.userId, "");
if (result.code !== 200) {
alert(result.msg);
}
if (!result.data) {
alert("No applications");
}
setsData(result.data);
}
fetchApplicationDataAsync();
}, [auth.userId]);
Another problem and bad practice is that you're not specifying your dependencies for the useEffect hook. You have 2 external dependencies: the auth.userId paramater and the ontext.fetchApplications function. We alleviate one of the problem by creating the fetch function in the body of useEffect itself. However, the auth.userId should go into the dependency array as stated above.
You have to check for fetchData to be defined before accessing its properties.
A short form would be
if (fetchData && fetchData.code !== 200){...}
Applied to your code:
React.useEffect(() => {
context.fetchApplications(auth.userId, "")
.then(function (fetchData) {
console.log("Fetched data: ", fetchData); ///this is undefined
if (fetchData && fetchData.code !== 200) { /// error part
alert(fetchData.msg);
}else {
alert("No applications");
}
setsData(fetchData.data);
});
}, []);
By calling then() on the fetchApplications() function, as follows, you pass to the callback the fullfilment value from the Promise returned by fetchApplications() (i.e. fetchData gets the value returned by fetchApplications()).
context.fetchApplications(auth.userId, "")
.then(function (fetchData) {...}
However, fetchApplications() returns a Promise that resolves with undefined because, actually, you don't return the Promises chain. This is why you get an error on fetchData.code.
Adapting fetchApplications() as follows (using await, since you use async) should do the trick (untested!):
async function fetchApplications(userId, role) {
try {
let dataArray = [];
let applicationRef = db
.collection('Users')
.doc(userId)
.collection('Applications');
const qs = await applicationRef.get();
qs.forEach(doc => {
console.log(doc.id, ' => ', doc.data());
console.log(doc.size, ' => ', typeof doc);
dataArray.push(doc.data());
});
return { code: 200, data: dataArray };
} catch (error) {
return { code: 400, msg: '시스템에러 고객센터에 문의해주세요' };
}
}
Note that in any case you return an object with a code property, so no more problem when doing fetchData.code.

How do I ensure I won't replace a content to an old response?

Good day for all,
I am doing a React course and I'd submited the code to the reviewer. He's returned me few comments and there is one comment I'm not being able to solve.
The comment is the following:
Check if (query === this.state.query) to ensure you are not going to replace the contents to an old response
And part of the code is the one below:
updateQuery = (query) => {
this.setState({
query: query
})
this.updateWantedBooks(query);
}
updateWantedBooks = (query) => {
if (query) {
BooksAPI.search(query).then((wantedBooks) => {
if (wantedBooks.error) {
this.setState({ wantedBooks: [] });
} else {
this.setState({ wantedBooks: wantedBooks });
}
})
} else {
this.setState({ wantedBooks: [] });
}
}
Anyone could help me what do am I suppose to do?
Regards.
Code reviewer is right, you don't really want to replace the response if user has entered the very same query.
You have to store somewhere what for user has searched recently:
this.setState({ wantedBooks: [], query });
In case of success response:
this.setState({ wantedBooks, query });
And then check it in case of further searches:
if (query && query !== this.state.query) {
// continue the search only if query is different that current
Instead of relying on an outer member which is open to abuse by other code, you can employ a factory function to more safely trap a member.
As you have discovered, trapping and testing query == this.state.query can be made to work but is arguably not the best solution available.
With a little thought, you can force each call of updateWantedBooks() automatically to reject the previous promise returned by the same function (if it has not already settled), such that any success callbacks chained to the previous promise don't fire its error path is taken.
This can be achieved with a reusable canceller utility that accepts two callbacks and exploits Promise.race(), as follows:
// reusable cancellation factory utility
function canceller(work, successCallback) {
var cancel;
return async function(...args) {
if (cancel) {
cancel(new Error('cancelled')); // cancel previous
}
return Promise.race([
work(...args),
new Promise((_, reject) => { cancel = reject }) // rejectable promise
]).then(successCallback);
};
};
Here's a demo ...
// reusable cancellation factory utility
function canceller(work, successCallback) {
var cancel;
return async function(...args) {
if (cancel) {
cancel(new Error('cancelled')); // cancel previous
}
return Promise.race([
work(...args),
new Promise((_, reject) => { cancel = reject })
]).then(successCallback);
};
};
// delay utility representing an asynchronous process
function delay(ms, val) {
return new Promise(resolve => {
setTimeout(resolve, ms, val);
});
};
function MySpace() {
// establish a canceller method with two callbacks
this.updateWantedBooks = canceller(
// work callback
async (query) => delay(500, query || { 'error': true }), // a contrived piece of work standing in for BooksAPI.search()
// success callback
(wantedBooks => this.setState(wantedBooks)) // this will execute only if work() wins the race against cancellation
);
this.setState = function(val) {
console.log('setState', val);
return val;
};
};
var mySpace = new MySpace();
mySpace.updateWantedBooks({'value':'XXX'}).then(result1 => { console.log('result', result1) }).catch(error => { console.log(error.message) }); // 'cancelled'
mySpace.updateWantedBooks(null).then(result2 => { console.log('result', result2) }).catch(error => { console.log(error.message) }); // 'cancelled'
mySpace.updateWantedBooks({'value':'ZZZ'}).then(result3 => { console.log('result', result3) }).catch(error => { console.log(error.message) }); // {'value':'ZZZ'} (unless something unexpected happened)
Note that canceller() doesn't attempt to abort the asynchronous process it initiates, rather it stymies the success path of the returned promise in favour of the error path.
I think reviewer's point is that response of Search API is asynchronous and result for "query 1" can arrive after user changed his mind and already requested search "query 2". So when response arrive - we need to check if we really interested in it:
updateQuery = query => {
this.setState({
query: query
wantedBooks: []
})
this.updateWantedBooks(query);
}
updateWantedBooks = query => {
if (query) {
BooksAPI.search(query).then((wantedBooks) => {
// if updateQuery("query1) and updateQuery("query2") called in a row
// then response for query1 can arrive after we requested query2
// => for some period of time we'll show incorrect search results
// so adding check if query still the same can help
if (query !== this.state.query) {
// outdated response
return;
} else if (wantedBooks.error) {
// query is okay, but server error in response
this.setState({
wantedBooks: []
})
} else {
// success response to requested query
this.setState({ wantedBooks });
}
})
}
}
Guys I´ve done some tests with your answers, but I realize that somehow the code was behavioring strangely.
So, I've seen in other part of the reviewer comments, a part which I hadn't had seen before do my answer here, the following comment:
Inside 'then' part of the promise check if(query === this.state.query) to ensure you are not going to replace the contents to an old response.
And this "Inside 'then'" has been beating in my brain.
So, I think I've arrived in a satisfatory code; sure, maybe it isn't the definite solution, that's why I want to show here for you and feel free to comment if I'd have to make some improvement. Here below I put the code:
updateQuery = (query) => {
this.setState({
query: query
})
this.updateWantedBooks(query);
}
updateWantedBooks = (query) => {
if (query) {
BooksAPI.search(query).then((wantedBooks) => {
if (wantedBooks.error) {
this.setState({ wantedBooks: [] });
} else if (query !== this.state.query) {
this.setState( { wantedBooks: [] });
} else {
this.setState({ wantedBooks: wantedBooks });
}
})
} else {
this.setState({ wantedBooks: [] });
}
}
Regards

Getting state updated very late and console error value was evaluated just now. How to resolve

I am totally confused about what's happening here. I am setting the state in React but it's updating very late. Here is the function:
fetchTimesheets() {
const userId = cryptInfo.decrypt(localStorage.getItem('user_id'))
var userArray = []
var timeSheets = []
fetchManagerProject(userId)
.then(async (res) => {
const projects = await res.json()
projects.forEach(project => {
project.teammember && project.teammember.forEach(member => {
if (userArray.indexOf(member.user) === -1) {
userArray.push(member.user)
fetchUserTimelogs(member.user)
.then(async (res) => {
const timesheet = await res.json()
if (timesheet)
timesheet.forEach(sheet => {
timeSheets.push(sheet)
});
})
}
})
})
this.setState({
timesheets: timeSheets
})
})
}
I am calling this function on componentDidMount method
componentDidMount() {
this.fetchTimesheets()
}
But I am getting that my value is evaluated just now and state is not updated. I have seen many questions related to this but didn't get a good solution.
Have you checked to see whether it is the requests that you are making that are taking a long time or whether it's the setState itself?
Your fetchTimesheets contains multiple http requests on a loop (forEach) which could take some time to complete depending on the request. Because the forEach loop is a blocking function it means that your setState function will not be called until the forEach functions execution has completed.
To speed this up, you could consider setting the timesheet in-state each time you get a new timesheet. For example
fetchManagerProject(userId)
.then(async (res) => {
const projects = await res.json()
projects.forEach(project => {
project.teammember && project.teammember.forEach(member => {
if (userArray.indexOf(member.user) === -1) {
userArray.push(member.user)
fetchUserTimelogs(member.user)
.then(async (res) => {
const timesheet = await res.json()
if (timesheet)
timesheet.forEach(sheet => {
timeSheets.push(sheet)
});
const newTimesheet = this.state.timesheets.concat(timesheet);
this.setState({timesheets: newTimesheet});
})
}
})
})
})
I believe that the function fetchTimesheets() is acting synchronously, you can change the function definition to be async and then call the method to be await fetchTimesheets().

Returning data from Axios API [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 3 months ago.
I am trying to use a Node.JS application to make and receive API requests. It does a get request to another server using Axios with data it receives from an API call it receives. The second snippet is when the script returns the data from the call in. It will actually take it and write to the console, but it won't send it back in the second API.
function axiosTest() {
axios.get(url)
.then(function (response) {
console.log(response.data);
// I need this data here ^^
return response.data;
})
.catch(function (error) {
console.log(error);
});
}
...
axiosTestResult = axiosTest();
response.json({message: "Request received!", data: axiosTestResult});
I'm aware this is wrong, I'm just trying to find a way to make it work. The only way I can seem to get data out of it is through console.log, which isn't helpful in my situation.
The issue is that the original axiosTest() function isn't returning the promise. Here's an extended explanation for clarity:
function axiosTest() {
// create a promise for the axios request
const promise = axios.get(url)
// using .then, create a new promise which extracts the data
const dataPromise = promise.then((response) => response.data)
// return it
return dataPromise
}
// now we can use that data from the outside!
axiosTest()
.then(data => {
response.json({ message: 'Request received!', data })
})
.catch(err => console.log(err))
The function can be written more succinctly:
function axiosTest() {
return axios.get(url).then(response => response.data)
}
Or with async/await:
async function axiosTest() {
const response = await axios.get(url)
return response.data
}
Guide on using promises
Info on async functions
I know this post is old. But i have seen several attempts of guys trying to answer using async and await but getting it wrong. This should clear it up for any new references
UPDATE: May 2022
This answer is still having lots of interest and have updated it to use arrow functions
const axiosTest = async () {
try {
const {data:response} = await axios.get(url) //use data destructuring to get data from the promise object
return response
}
catch (error) {
console.log(error);
}
}
you can populate the data you want with a simple callback function,
let's say we have a list named lst that we want to populate,
we have a function that pupulates pupulates list,
const lst = [];
const populateData = (data) => {lst.push(data)}
now we can pass the callback function to the function which is making the axios call and we can pupulate the list when we get data from response.
now we make our function that makes the request and pass populateData as a callback function.
function axiosTest (populateData) {
axios.get(url)
.then(function(response){
populateData(response.data);
})
.catch(function(error){
console.log(error);
});
}
The axios library creates a Promise() object. Promise is a built-in object in JavaScript ES6. When this object is instantiated using the new keyword, it takes a function as an argument. This single function in turn takes two arguments, each of which are also functions — resolve and reject.
Promises execute the client side code and, due to cool Javascript asynchronous flow, could eventually resolve one or two things, that resolution (generally considered to be a semantically equivalent to a Promise's success), or that rejection (widely considered to be an erroneous resolution). For instance, we can hold a reference to some Promise object which comprises a function that will eventually return a response object (that would be contained in the Promise object). So one way we could use such a promise is wait for the promise to resolve to some kind of response.
You might raise we don't want to be waiting seconds or so for our API to return a call! We want our UI to be able to do things while waiting for the API response. Failing that we would have a very slow user interface. So how do we handle this problem?
Well a Promise is asynchronous. In a standard implementation of engines responsible for executing Javascript code (such as Node, or the common browser) it will resolve in another process while we don't know in advance what the result of the promise will be. A usual strategy is to then send our functions (i.e. a React setState function for a class) to the promise, resolved depending on some kind of condition (dependent on our choice of library). This will result in our local Javascript objects being updated based on promise resolution. So instead of getters and setters (in traditional OOP) you can think of functions that you might send to your asynchronous methods.
I'll use Fetch in this example so you can try to understand what's going on in the promise and see if you can replicate my ideas within your axios code. Fetch is basically similar to axios without the innate JSON conversion, and has a different flow for resolving promises (which you should refer to the axios documentation to learn).
GetCache.js
const base_endpoint = BaseEndpoint + "cache/";
// Default function is going to take a selection, date, and a callback to execute.
// We're going to call the base endpoint and selection string passed to the original function.
// This will make our endpoint.
export default (selection, date, callback) => {
fetch(base_endpoint + selection + "/" + date)
// If the response is not within a 500 (according to Fetch docs) our promise object
// will _eventually_ resolve to a response.
.then(res => {
// Lets check the status of the response to make sure it's good.
if (res.status >= 400 && res.status < 600) {
throw new Error("Bad response");
}
// Let's also check the headers to make sure that the server "reckons" its serving
//up json
if (!res.headers.get("content-type").includes("application/json")) {
throw new TypeError("Response not JSON");
}
return res.json();
})
// Fulfilling these conditions lets return the data. But how do we get it out of the promise?
.then(data => {
// Using the function we passed to our original function silly! Since we've error
// handled above, we're ready to pass the response data as a callback.
callback(data);
})
// Fetch's promise will throw an error by default if the webserver returns a 500
// response (as notified by the response code in the HTTP header).
.catch(err => console.error(err));
};
Now we've written our GetCache method, lets see what it looks like to update a React component's state as an example...
Some React Component.jsx
// Make sure you import GetCache from GetCache.js!
resolveData() {
const { mySelection, date } = this.state; // We could also use props or pass to the function to acquire our selection and date.
const setData = data => {
this.setState({
data: data,
loading: false
// We could set loading to true and display a wee spinner
// while waiting for our response data,
// or rely on the local state of data being null.
});
};
GetCache("mySelelection", date, setData);
}
Ultimately, you don't "return" data as such, I mean you can but it's more idiomatic to change your way of thinking... Now we are sending data to asynchronous methods.
Happy Coding!
axiosTest() needs to return axios.get, which in turn returns a Promise.
From there, then can be used to execute a function when said Promise resolves.
See Promise for more info.
Alternatively, await can be used from within the scope of some async function.
// Dummy Url.
const url = 'https://jsonplaceholder.typicode.com/posts/1'
// Axios Test.
const axiosTest = axios.get
// Axios Test Data.
axiosTest(url).then(function(axiosTestResult) {
console.log('response.JSON:', {
message: 'Request received',
data: axiosTestResult.data
})
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.js"></script>
IMO extremely important rule of thumb for your client side js code is to keep separated the data handling and ui building logic into different funcs, which is also valid for axios data fetching ... in this way your control flow and error handlings will be much more simple and easier to manage, as it could be seen from this
ok fetch
and this
NOK fetch
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
function getUrlParams (){
var url_params = new URLSearchParams();
if( window.location.toString().indexOf("?") != -1) {
var href_part = window.location.search.split('?')[1]
href_part.replace(/([^=&]+)=([^&]*)/g,
function(m, key, value) {
var attr = decodeURIComponent(key)
var val = decodeURIComponent(value)
url_params.append(attr,val);
});
}
// for(var pair of url_params.entries()) { consolas.log(pair[0]+ '->'+ pair[1]); }
return url_params ;
}
function getServerData (url, urlParams ){
if ( typeof url_params == "undefined" ) { urlParams = getUrlParams() }
return axios.get(url , { params: urlParams } )
.then(response => {
return response ;
})
.catch(function(error) {
console.error ( error )
return error.response;
})
}
// Action !!!
getServerData(url , url_params)
.then( response => {
if ( response.status === 204 ) {
var warningMsg = response.statusText
console.warn ( warningMsg )
return
} else if ( response.status === 404 || response.status === 400) {
var errorMsg = response.statusText // + ": " + response.data.msg // this is my api
console.error( errorMsg )
return ;
} else {
var data = response.data
var dataType = (typeof data)
if ( dataType === 'undefined' ) {
var msg = 'unexpected error occurred while fetching data !!!'
// pass here to the ui change method the msg aka
// showMyMsg ( msg , "error")
} else {
var items = data.dat // obs this is my api aka "dat" attribute - that is whatever happens to be your json key to get the data from
// call here the ui building method
// BuildList ( items )
}
return
}
})
</script>
After 6 hours of fluttering, I realized it was a one-line problem. If you are interfering with the axios life-cycle, you may have forgotten this line:
componentDidMount() {
this.requestInterceptor = axios.interceptors.request.use((request) => {
this.updateApiCallFor(request.url, true);
return request;
});
this.responseInterceptor = axios.interceptors.response.use((response) => {
this.updateApiCallFor(response.config.url, false);
return response; // THIS LINE IS IMPORTANT !
}, (error) => {
this.updateApiCallFor(error.config.url, false);
throw error;
});
async makes a function return a Promise
await makes a function wait for a Promise
code async/await
// https://www.npmjs.com/package/axios
const axios = require('axios')
/* --- */
async function axiosTest() {
let promiseAxios = axios.get( 'https://example.com' )
/* --- */
console.log( await promiseAxios )
}
/* --- */
axiosTest()
replit.com Stackoverflow - Returning data from Axios API
replit.com Stackoverflow - How to return values from async
code async/await with return
// https://www.npmjs.com/package/axios
const axios = require('axios')
/* --- */
async function axiosTest() {
console.log( await promiseAxios() )
}
/* --- */
axiosTest()
/* --- */
// create function for promise axios and return it
function promiseAxios() {
return axios.get( 'https://example.com' )
}
replit.com Stackoverflow - Returning data from Axios API - return
replit.com Stackoverflow - How to return values from async - return
Try this,
function axiosTest() {
axios.get(url)
.then(response => response.data)
.catch(error => error);
}
async function getResponse () {
const response = await axiosTest();
console.log(response);
}
getResponse()
It works, but each function where you want to get the response needs to be an async function or use an additional .then() callback.
function axiosTest() {
axios.get(url)
.then(response => response.data)
.catch(error => error);
}
async function getResponse () {
axiosTest().then(response => {
console.log(response)
});
}
getResponse()
If anyone knows a way to avoid this please do tell.
Also checkout Katsiaryna (Kate) Lupachova's article on Dev.to. I think it will help.
async handleResponse(){
const result = await this.axiosTest();
}
async axiosTest () {
return await axios.get(url)
.then(function (response) {
console.log(response.data);
return response.data;})
.catch(function (error) {
console.log(error);
});
}
You can find check https://flaviocopes.com/axios/#post-requests url and find some relevant information in the GET section of this post.
You can use Async - Await:
async function axiosTest() {
const response = await axios.get(url);
const data = await response.json();
}

Categories

Resources