skip to Main Content

My VueJS running app displays activity data from Strava, grouped together by week, over a 20-week period. The difficulty that I’m having is that the object from my API appears, but I cannot access each property.

These are the relevant excerpts from the SFC.

DATA

weekly_total_data will grow as the weeks progress

data() {
        {
            return {
            activity_weeks: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20],
            weekly_total_data:
               [{"week_number":3,"total_distance":39877.6,"total_moving_time":11841},
                {"week_number":2,"total_distance":58596.4,"total_moving_time":18719},     
                {"week_number":1,"total_distance":41347.5,"total_moving_time":12796}]
            }
        }
    }

FUNCTION

Acccessing the data

    matchWeeklyTotals(){
        var x = this.weekly_total_data
        console.log(x)
        return x
      }
    },

TEMPLATE

Looping through the weeks, getting an index for each week, and then using that to display the appropriate data for the week

<div v-for="(week, week_index) in this.activity_weeks" v-bind:value="week._id">
   <div class="container max-w-xl mx-auto">
       <h2 class="text-2xl">Week {{week}}: {{ (matchWeeklyTotals()[week_index])}}</h2>
   </div>
</div>

As it stands, I can display the object, but when I do matchWeeklyTotals()[week_index][total_distance], as an example, it fails.
I have also tried variations of JSON.parse.

Any help to access the total_distance and total_moving_time appreciated.

3

Answers


  1. If you are trying to access data through a getter, make sure your getter is a computed property

    export default {
    ...,
    computed: {
    matchWeeklyTotals() {
    return this.weekly_total_data;
    }
    }
    }
    

    And when you access them in the template, you don’t need to call the function using parenthesis, so you can access them directly as

    <h2>
    {{ (matchWeeklyTotals[week_index])}}
    </h2>
    

    Also I would recommend adding a check to ensure if the item of that weekIndex exists, and if possible match the week_number number value and use a find function, or map the array in a form where you can access the data directly in case there’s a sorting issue in the data at some point. You could also map the weekly_total_data array directly, unless there’s a specific reason to have multiple arrays

    Login or Signup to reply.
  2. The following code is working.

    I’m filtering weekly_total_data to check if the activity_weeks exists in weekly_total_data => week_number

    <script setup>
    const activity_weeks = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
    
    const weekly_total_data = [
      {"week_number":3,"total_distance":39877.6,"total_moving_time":11841},
      {"week_number":2,"total_distance":58596.4,"total_moving_time":18719},
      {"week_number":1,"total_distance":41347.5,"total_moving_time":12796}
    ]
    
    const matchWeeklyTotals = () => {
      var x = weekly_total_data
      console.log(x)
      return x
    }
    
    </script>
    
    <template>
      <div v-for="week in weekly_total_data.filter(x => x.week_number in activity_weeks)">
         <div class="container max-w-xl mx-auto">
             <h2 class="text-2xl">Week {{week.week_number}}: {{ week.total_distance }}</h2>
         </div>
      </div>
    </template>
    
    Login or Signup to reply.
  3. If I understood You correctly, You can use optional chaining:

    const app = Vue.createApp({
      data() {
        return {
          activity_weeks: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20],
          weekly_total_data: [
            {"week_number":3,"total_distance":39877.6,"total_moving_time":11841},
            {"week_number":2,"total_distance":58596.4,"total_moving_time":18719},     
            {"week_number":1,"total_distance":41347.5,"total_moving_time":12796}
          ]
        }
      },
    })
    app.mount('#demo')
    <script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
    <div id="demo">
      <div v-for="(week, week_index) in activity_weeks" v-bind:value="week._id">
        <div class="container max-w-xl mx-auto">
          <h2 class="text-2xl">Week {{ week }}:</h2>
          <p>{{ weekly_total_data[week_index]?.total_distance }}</p>
          <p>{{ weekly_total_data[week_index]?.total_moving_time }}</p>
        </div>
      </div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search