I would like to make two api call's at once to a ReST API in my vue component. I have done research online and am using this logic:
// Multiple fetches
Promise.all([
fetch(
`https://api.covid19api.com/live/country/${this.selected}/status/confirmed/date/${this.yesterday}`
),
fetch(
`https://api.covid19api.com/live/country/south-africa/status/confirmed/date/2020-03-21T13:13:30Z`
)
])
.then(responses => {
// Get a JSON object from each of the responses
return responses.map(response => {
return response.json();
});
})
.then(data => {
// Log the data to the console
// You would do something with both sets of data here
this.coronaVirusStats1 = data[0];
console.log(this.coronaVirusStats1);
})
.catch(function(error) {
// if there's an error, log it
console.log(error);
});
}
The consoled value is a promise which I understand but when I look in the Vue devTools under my component I see that coronaVirusStats1 has a value of "Promise", not the array of objects I expect back. When I do a single fetch and consume the data variable there is no problem. However I am perplexed as to how one accesses the returned data from fetch calls to multiple endpoints. I tried all the solutions here fetching api's ,but none worked. If someone can elucidate on the proper way to access the data from the fetches I would be most appreciative.
You're just about there. The issue is that your first then returns an array of promises. Unfortunately, promise chains only work with a Promise instance so there's nothing here that will wait for your promises to resolve.
The quick fix is to change the first then to
return Promise.all(responses.map(r => r.json()))
That being said, there's a little more to the fetch API, particularly for dealing with errors.
I would use something like the following for each fetch call to make sure network errors and non-successful HTTP requests are handled correctly.
This will also handle unwrapping the JSON response so you don't have to use the above
Promise.all([
fetch(url1).then(res => res.ok && res.json() || Promise.reject(res)),
fetch(url2).then(res => res.ok && res.json() || Promise.reject(res))
]).then(data => {
// handle data array here
})
See https://developer.mozilla.org/en-US/docs/Web/API/Response/ok
Related
'''if (await permission()) {
Geolocation.getCurrentPosition(
async position => {
await fetch(
`https://api.opencagedata.com/geocode/v1/json?q=${position.coords.latitude}+${position.coords.longitude}&key=apikey&pretty=1`,
).then(result => {
console.log(result.data);
});
},
error => {
console.log(error.code, error.message);
},
);
}'''
How do i retrive the returned location from the response sent to me
The things it sends me seems like gibrish and have no clue what to do and i am building the app in react-native using tsx
All you need to do is console the response to make sure that you are receiving your response as expected after that you've multiple choices to extract the required data e.g. Destructuring or looping through the response (quite expensive + time taking) or you can use the filter method, in a nutshell, there are tons of way to get your required data from the response and it's just a matter of your taste(like whichever you prefer)
I'm making a simple API in express js. I've an end point where I'll make a call to GitHub api int turn. My Front-end application will utilize it. Here is my code:
api.js
const express = require('express');
const router = express.Router();
...
var http = require('http');
var https = require("https");
router.get('/github', function (req, res) {
// APPROACH 1: Failed : fetch is not defined
// fetch('https://api.github.com/users/tmtanzeel')
// .then(response => response.json())
// .then(json => console.log(json))
// APPROACH 2: Failed : throw er; // Unhandled 'error' event
/*try {
https.get('https://api.github.com/users/tmtanzeel',function (res) {
console.log(res);
})
} catch (error) {
...
}*/
});
Both my approaches are failing. I've almost no experience with Express. Please picth in
The second method is almost corrent. Add the error handler and send to the caller the data you just received.
https.get('https://api.github.com/users/tmtanzeel',function (apiRes) {
apiRes.pipe(res);
}).on('error', (e) => {
console.error(e);
res.status(500).send('Something went wrong');
});
Handling the response (stream) received from the API call can be done in two ways.
Using pipes which is automatic
Handle read events and manage the data writing manually
I have used the first approach.
However, it is very well recommended that you get sound knowledge in handling Streams if you use Node JS. Streams are the basis of Node JS requests and responses.
https://nodejs.dev/learn/nodejs-streams
You should use Express to handle incoming requests.
(for example if your webapp fetches data from your (express) server).
Read the docs: http://expressjs.com
Your first attempt failed because fetch is an implementation of the web-browser, not one of nodejs.
If you want to use fetch try: https://www.npmjs.com/package/node-fetch
its a well documented, easy to use fetch function.
From your examples, all seems fine except I can't see you sending the returned data to the client.
You can try something similar like adding res.send(data) to send the data and make it available on the /github route
I have weird results displayed in the web console:
fetch() is sending duplicated requests to the same url.
I thought it could be something related to fetch(), but also noticed that on reload of the app (quasar, based on webpack) also the requests to the http://localhost:8080/sockjs-node/info are duplicated.
By contrast, I noticed that requests handled by jQuery are NOT duplicated and works fine.
I cannot say if it is an error due to webpack configuration, fetch or they way I am using it i Vue components.
E.g. This article points out possible causes https://insights.daffodilsw.com/blog/how-to-avoid-duplicate-api-requests but in my case it is not due to user interaction : requests are triggered at time of relaunching the app (webpack), and particularly the stack trace shows that the requests are fired at time of creating the components, just multiple times.
Example of how I am using fetch():
// component -
methods : {
search(input) {
return new Promise(resolve => { // a new promise is request multiple times, in spite in created() it is called just once
var _base = 'myEndpoint/api'
const url = `${_base}fuzzyautocomplete?q=${encodeURI(input)}`
if (input.length < 3) {
return resolve([])
}
fetch(url) // so promises are actually different, and duplicated requests are fired by fetch
.then(response => response.json())
.then(data => {
console.log(data)
// resolve(data.query.search)
resolve(data)
})
})
},
....
// and it should be called just once at time of creation
created() {
this.search('init first query !!');
}
Could you advise?
I try to use fetch() to get the data from https://swapi.co/
With this code I get undefined but in the "Network" section in chrome I see the data I need. How I can access it?
fetch('https://swapi.co/api/people/1/')
.then(resp => resp.json)
.then(obj => console.log(obj));
Hello this will fetch the data returning it as json
fetch('https://swapi.co/api/people/1')
.then(function(response) {
return response.json();
})
.then(function(myJson) {
console.log(JSON.stringify(myJson));
});
If you have right environment for calling to the fetch API there maybe 2 result
You will get the right result data
You will get an error
fetch(url) // Call the fetch function passing the url of the API as a parameter
.then(function() {
// Your code for handling the data you get from the API
})
.catch (function() {
// This is where you run code if the server returns any errors
});
Use a catch for seen what is going wrong with your request
Im making a website with Nuxtjs, i want when i open any page of the website to get user information from the server using Axios, and i want to use these information to call another API's from the website.
For example: i will get the User id and Client id from the server and use them on the API URL, lets say i got User id = 5, Client id = 10
i will call another API's and use these informations
http://****/getItems?userid=5&clientid=10
Now my problem is the second API call before the first API finished so i didn't got the user informations yet.
Could you please help me with this issue, note that i want to get the user information on all pages. so if i reload the page in any page i want to get user informations.
So i call the user information API from a Layout and call the other API's from another components.
Thanks.
First you should use Axios module officially provided by Nuxt.js here, https://github.com/nuxt-community/axios-module. They have make the integration between Axios and Nuxt.js easier.
Axios uses promise so you can easily chaining method to do it. Let say you wanna get information from /get/product with data gotten from the url you mention before http://****/getItems?userid=5&clientid=10, you can easily do that like this
this.$axios.$get('/getItems?userid=5&clientid=10')
.then(data => {
// You can use your data received from first request here.
return this.$axios.$post('/get/product', {
id: data.id,
clientId: data.clientId
})
})
.then(data => {
// You can use your data received from second request here.
console.log(data)
})
Explanation
This part,
this.$axios.$get('/getItems?userid=5&clientid=10')
the axios will get the data from the url provided, when the data is received, we can use it within then() block as it accept callback as a parameter.
.then(data => {
// You can use your data received from first url here.
...
})
After that, if you wanna use your data you can easily return the axios request again with proper parameter you wanna send.
return this.$axios.$post('/get/product', {
id: data.id,
clientId: data.clientId
})
And again you can use the data received from second axios request within then() block.
.then(data => {
// You can use your data received from second request here.
console.log(data)
})
Updated
Oke, based on the clarification on the comment section below. We can return the axios promise in first action and then on the second method we can dispatch the first action,
actions: {
callFirst ({ commit }) {
return this.$axios.$get('/get/first')
.then(firstResult => {
commit('SET_FIRST', firstResult)
return firstResult
})
},
callSecond ({ dispatch, commit }) {
return dispatch('callFirst').then(firstResult => {
return this.$axios.$post(`/get/${firstResult.userId}`)
.then(secondResult => {
commit('SET_SECOND', secondResult)
return secondResult
})
})
}
}
Using that way, you just need to put the callSecond() action whereever you want get the second data. And you also don't need to put the callFirst() action on default.vue.