Call API with Another Api response data in Nuxtjs - vuejs2

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.

Related

Duplicated requests to same url with fetch using vue and webpack

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?

Making multiple api requests at once using fetch in vue

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

Using vue router BeforeRouteEnter method to wait for http request to complete

Hi I'm trying to make it so that when a user opens a page it won't open until the data from the server is successfully retrieved so that it won't appear after 0.5s or so after the user enters.
To do this I read that I need to use BeforeRouteEnter but I'm having trouble finding information on how to properly use this, especially with waiting for my REST API to complete its request.
Here's the method I want to wait to complete before routing to my new component:
async getThread() {
const response = await postsService.fetchOneThread({
id: this.blockId,
topic: this.topicId,
thread: this.postId
});
this.thread = response.data;
}
so once this.thread = response.data only then do I want the page to display.
An important thing to note is that I am also passing through URL parameters to get the data which is the topic/black/post ID.
Here is my getUrlParam method also
url() {
let x = this.$route.params.topic.split('-');
this.topicId = x[0];
let y = this.$route.params.id.split('-');
this.blockId = y[0];
let post = this.$route.params.thread.split('-');
this.postId = post[1];
this.getThread();
}
Thanks
You need to move getThread inside beforeRouteEnter
beforeRouteEnter: (to, from, next) => {
postsService.fetchOneThread({
id: this.blockId,
topic: this.topicId,
thread: this.postId
}).then( response => {
//store the data somewhere accessible
next()
})
},
A few notes:
I don't think beforeRouteEnter can be async, so I'm using then to get the response
the component is not yet ready, so you can't access it yet, you need to save the information some other place so it can be read by the component. I'd suggest using Vuex for this.
If you decide to use Vuex than you need to add a mutation and call it from the promise's callback.
store.commit('ADD_THREAD', response.data)

Using fetch() with API

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

React-native Fetch GET, while passing request items to the url

I have a Django-REST API that I am trying to access with a React-native app. I would like to achieve the same result that the command line
http GET http://mywebsite.com/api param1=value1 param2=value2
but using the fetch() function from the networking tutorial. How can I specify the request items to the fetch while using the GET method?
EDIT: my goal is to able to perform a token authentication to a django rest API which need these request item for the page to be accessed.
fetch() uses the exact URL string you provide to perform the request.
Include URL params in your url like when you are calling fetch()
fetch("http://whatever.xyz?param1=1&param2=2")
The simplest way to handle this is by using something similar to the following function
function apiCall() {
return fetch('http://mywebsite.com/api/?param1=value1&param2=value2')
.then((response) => response.json())
.then((responseJson) => {
return responseJson.movies;
})
.catch((error) => {
console.error(error);
});
}