Trouble with accessing Object property in vue

1.4k views Asked by At

I am trying to access an Object property in vue component computed property but I am getting an error saying the property is undefined. I have setup a prototype here. When I try to use

playerEntry.stats.RecYards["#text"] > "0"

Vue complains

[Vue warn]: Error in render: "TypeError: playerentry.stats.RecYards is undefined"

and looking in vue.js devtools under Computed I see playerReceivingStats:"(error during evaluation)" here is the pertinent code:

boxscore.js

const boxScoresStats = {
  stats: Vue.component("box-scores", {
    props: ["props_box_score", "props_gameID"],
    data: function() {
      return {
        playerStats: this.props_box_score.data.gameboxscore.awayTeam.awayPlayers
          .playerEntry
      };
    },
    computed: {
      playerPassingStats: function() {
        return this.playerStats.filter(playerEntry => {
          return playerEntry.player.Position === "QB";
        });
      },
      playerReceivingStats: function() {
        return this.playerStats.filter(playerEntry => {
          console.log(playerEntry.stats.RecYards["#text"]);
          return playerEntry.stats.RecYards["#text"] > "0";
        });
      }
    },

Template

<div v-for="playerStats in playerReceivingStats">
    <tr class="d-flex">
        <td class="col-3 justify-content-center" scope="row">
        {{playerStats.player.FirstName}} {{playerStats.player.LastName}} ({{playerStats.player.Position}})
        </td>
        <td class="col-2 justify-content-center" justify-content="center">
            {{ playerStats.stats.Receptions['#text'] }} </td>
        <td class="col-3 justify-content-center">{{playerStats.stats.RecYards['#text']}}</td>
        <td class="col-2 justify-content-center">{{playerStats.stats.RecTD['#text']}}</td>
        <td class="col-2 justify-content-center">{{playerStats.stats.Targets['#text']}}</td>
    </tr>
</div>

I have tried both bracket and dot notation but still no good. I see the values from the console.log printing out ok. But I am at a loss as to why it says undefined when I can see the object property in devtools. Also note if I shorten the eval in computed to playerEntry.stats.RecYards I get no error? But I then get incorrect results. Any help much appreciated.

Updated:

Here is the computed property that works:

 playerReceivingStats: function() {
        return this.offensivePlayers.filter(playerEntry => {
          if (typeof playerEntry.stats.RecYards != "undefined") {
            return playerEntry.stats.RecYards["#text"] > "0";
          }
        });
      }
    }
2

There are 2 answers

8
chans On

You need to add created hook to set the props value to data property

data: function() {
      return {
        playerStats: { 
         stats: {
           RecYards: {}
         }
        },
      };
    },
created() {
  this.playerStats = this.props_box_score
                         .data.gameboxscore.awayTeam.awayPlayers.playerEntry;
}
0
Blaine Lafreniere On

Your child component has probably loaded before the data has become available in the parent component. Remember, JavaScript is asynchronous, so your component rendering may be happening before the data is even available.

You can use conditional rendering on your component to render the component once the data is available.

<my-component v-if="someCondition">

You will then need to go through your code, find the point at which that data becomes available, and then set someCondition = true, once this flag is flipped, your component will render, and the data it is dependent upon will be available.

Use v-if as opposed to v-show. If you use v-show, your component will eagerly render but just be hidden by CSS. If you use v-if your component will lazily render once the condition is true.