-1

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";
          }
        });
      }
    }
Nimantha
  • 6,405
  • 6
  • 28
  • 69
Alan
  • 1,067
  • 1
  • 23
  • 37
  • 1
    The `RecYards` property is missing for that player. When I try it it seems to be `Logan Cooke`, id `14702`, `this.playerStats[11]`. The logging you're seeing is for the first few players, which work fine, but it falls over when it gets to that player. – skirtle Oct 10 '19 at 16:49
  • Try setting `playerStats` as a computed property instead of a data property. – Ricky Ruiz Oct 10 '19 at 17:01
  • 1
    Regarding the update: It is `playerStats[11]` that is missing the relevant field. The picture shows `playerStats[0]`. – skirtle Oct 10 '19 at 18:26

2 Answers2

0

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;
}
chans
  • 5,104
  • 16
  • 43
  • Sorry still getting "playerEntry.stats.RecYards is undefined" with update. – Alan Oct 10 '19 at 17:10
  • Can you please try again with the above approach? – chans Oct 10 '19 at 17:14
  • Sorry still "RecYards undefined" – Alan Oct 10 '19 at 17:50
  • 2
    `props` are available within the `data` function, you don't need to use `created` to copy them across. There's an example of this within the official documentation, https://vuejs.org/v2/guide/components-props.html#One-Way-Data-Flow – skirtle Oct 10 '19 at 17:51
  • Yes I see because computed property "playerPassingStats" uses "playerEntry.player.Position" no problem. Any ideas on what is going on here? – Alan Oct 10 '19 at 17:54
  • 1
    @Alan I believe I have already explained what the problem is in the comment I posted on the question. The data you're trying to use is simply missing from the server response. – skirtle Oct 10 '19 at 17:56
  • See updated image from devtools. Do I not see "playerEntry.stats.RecYards' in copy. And I can console.log the object property? – Alan Oct 10 '19 at 18:03
  • my fault. I didnt look thru all the results. I will have to put an additional test in function check. Thanks! – Alan Oct 10 '19 at 18:27
0

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.

Blaine Lafreniere
  • 3,451
  • 6
  • 33
  • 55