1

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:

  1. I make the first axios request in vuex and use v-for to display each user name: 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> 
  1. I then need to make another GET request for performance: 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
      }
  1. and lastly for the users that have a performance ID I need to get the measurements: 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!

2
  • Just to clarify, the 1st request gives you a list of users with their IDs, the 2nd is for the details of a specific user, and the 3rd is for a specific user's 'performance details'? Why doesn't the 1st request return the User's performance ID? Commented Aug 24, 2020 at 16:36
  • Yes exactly! The last gives all the measurements and I need performance Id to get them. I wish it did, I'm using an api though and this is how it was given to me. Commented Aug 24, 2020 at 16:46

1 Answer 1

1

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>
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks so much, this works great! But how can I show the specific details? Like if I get back data [{ key: "temp" data: "38", },{"key": "vol", "data": "22"}]I want to show 38 in the Temperature box and 22 in Volume for whichever user returned that data. Otherwise if user didn't return data I just want an empty box.
Well, the same way you're displaying your User's names. Save the performance data into your profiles Object, and just refer to each key as needed. If you'd like to show the performance-wrapper div just with empty details, let me know and I'll modify my answer
Thanks so much!! Yes I want it empty if there is no data, thanks so much for adding it!
Also for saving the performance data in profiles, does it make a difference that profiles is in vuex?
Even better if it's in a Vuex store, you can just save it from wherever you want in that case and access the store whenever you need the performance details as well. Performance will be better long term, since there's going to be less API calls
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.