Reputation: 91
I have a user profile card that displays different measurements in boxes, such as temperature, volume and weight.
Currently I'm getting the name of each user from an axios GET request, I need to then take the ID in that data and perform another GET request with the ID which gives me a performance data, in that data I am given a performance ID which I need to use to GET a final array of measurement data.
I'm wondering how I can make the last GET request only for users that have a performance Id and then take that data of the measurements and display in each user profile{that has measurement data) for each measurement box?
It looks something like this:
GET api/profiles
which returns:"data": [
{
"id": 1,
"name": "Joe",
},
{
"id": 2,
"name": "Max",
},
<div class="outer" v-for="(item, index) in profiles" :key="item.id" >
<p> User Name: {{ item.name }}</p>
GET api/performance/{profileID}
which returns only for users who have (other users return empty data object):mounted() {
this.$store.state.profiles.forEach((item, index) => {
axios.get('api/performance/' + this.profile[index].id)
.then(response => {
this.performanceId = response.data.data.id
})
});
}
"data": {
"id": 1,
"profile_id": 2,
.....other keys and values
}
GET api/measurements/{profileID}/{performanceID}
which returns:"data": {
"profileID": "2",
"perfomanceID": "1",
"data": [
{
"key": "temp",
"data": "37",
},
{
"key": "vol",
"data": "22",
},
{
"key": "weight",
"data": "200",
},
I would then like each data point to display in the box:
<div class="outer" v-for="(item, index) in profiles" :key="item.id" >
<p> User Name: {{ item.name }}</p>
<div class="box 1">Temperature: </div>
<div class="box 2">Volume: </div>
<div class="box 3">Weight: </div>
</div>
It would like this for Max's profile:
User Name: Max
Temperature: 37
Volume: 22
Weight: 200
Any help would be appreciated, thanks!
Upvotes: 1
Views: 1464
Reputation: 1106
If I understood you right, this is how I'd go about it.
Assuming there's no way to check whether a user has a performance ID other than making a request first, you can have a data()
prop, for example hasPerformanceDetails
which is set to false
by default. Once you query the API for the performance ID, you can check whether it returned anything, and if it did just set hasPerformanceDetails
to true
. Then you just render the parts of the profile with the performance details using a v-if
or v-show
directive.
Something like this
data() {
return { hasPerformanceDetails: false }
},
created() {
this.populateProfile()
},
methods: {
populateProfile() {
// Call the measurements endpoint and check if response is empty or not
if (apiResponse != null) {
this.hasPerformanceDetails = true;
}
}
}
And in your <template>
<div class="outer" v-for="(item, index) in profiles" :key="item.id" >
<p> User Name: {{ item.name }}</p>
<div v-if="hasPerformanceDetails" class="performance-wrapper">
<div class="box 1">Temperature: </div>
<div class="box 2">Volume: </div>
<div class="box 3">Weight: </div>
</div>
</div>
Keep in mind it's the best to call the API on the created()
hook, as this is before anything gets rendered or mounted into the DOM. See this answer for a reference. Vue will do the request, and only once all the data is there will it exit the created()
hook and modify the items in data()
.
You can alternatively use v-show
. v-if
will straight up not render anything at all, v-show
will have the section in the HTML but hide it using display: none
Alternatively, if you want the performance-wrapper
div to always be there, but just empty, you can use a ternary operator instead
<div class="outer" v-for="(item, index) in profiles" :key="item.id" >
<p> User Name: {{ item.name }}</p>
<div class="box 1">Temperature: {{ hasPerformanceDetails ? item.temp : "Not available" }}</div>
<div class="box 2">Volume: {{ hasPerformanceDetails ? item.volume : "Not available" }}</div>
<div class="box 3">Weight: {{ hasPerformanceDetails ? item.weight : "Not available" }}</div>
</div>
Upvotes: 1