Cannot read property of undefined, but property exists


#1

Hello all,
I am getting a curious error in a template helper and I was hoping someone could lay eyes on it with me. Basically the error I’m getting in the console of the client is that the getArena().height is undefined. However, console.log(getArena().height) returns the correct property value. It appears to be a timing issue causing me to get the error, but my application is actually working. What can I do to alleviate this console error?

//My template helper function
yGrids: function() {

        console.log(getArena);
        console.log(getArena().height);
        var yArray = [];
        for (var i=0;i<(getArena().height);i++){
            yArray.push({});
        }
        return yArray;
    },
    
    
// The console results
function getArena() {                                                                                              // 50
    return Arenas.findOne(Session.get('arena_id'));                            …
Exception in template helper: TypeError: Cannot read property 'height' of undefined
    at Object.yGrids (http://localhost:3000/app/app.js?hash=c17abf51d6af6541e868fa3fd0b26e34eea2df28:94:35)
    at http://localhost:3000/packages/blaze.js?hash=ef41aed769a8945fc99ac4954e8c9ec157a88cea:2994:16
    at http://localhost:3000/packages/blaze.js?hash=ef41aed769a8945fc99ac4954e8c9ec157a88cea:1653:16
    at http://localhost:3000/packages/blaze.js?hash=ef41aed769a8945fc99ac4954e8c9ec157a88cea:3046:66
    at Function.Template._withTemplateInstanceFunc (http://localhost:3000/packages/blaze.js?hash=ef41aed769a8945fc99ac4954e8c9ec157a88cea:3687:12)
    at http://localhost:3000/packages/blaze.js?hash=ef41aed769a8945fc99ac4954e8c9ec157a88cea:3045:27
    at Object.Spacebars.call (http://localhost:3000/packages/spacebars.js?hash=65db8b6a8e3fca189b416de702967b1cb83d57d5:172:18)
    at http://localhost:3000/app/app.js?hash=c17abf51d6af6541e868fa3fd0b26e34eea2df28:24:22
    at .<anonymous> (http://localhost:3000/packages/blaze.js?hash=ef41aed769a8945fc99ac4954e8c9ec157a88cea:2754:17)
    at http://localhost:3000/packages/blaze.js?hash=ef41aed769a8945fc99ac4954e8c9ec157a88cea:1875:20
function getArena() {                                                                                              // 50
    return Arenas.findOne(Session.get('arena_id'));                            …
2

#2

How about checking if getArena() actually returns the required object before trying to access member properties?

yGrids: function() {
 var a = getArena();
 var yArray = [];
 if(a != undefined) {
  for (var i=0;i<(a.height);i++){
   yArray.push({});
  }
 }
 return yArray;
},

#3

Yes, I can add in manual validation like you suggest. I’m more curious if I’m doing something wrong that causes this to happen in the first place. Is there a best-practice for this sort of thing?


#4

I resolved it by doing the following, wrapping the whole functions contents in an if statement that confirms getArena() exists before I execute the function. Its ugly and I’d prefer not doing that, but unless theres a better way …

yGrids: function() {
        if(getArena()) {
            var yArray = [];
            for (var i = 0; i < (getArena().height); i++) {
                yArray.push({});
            }
            return yArray;
        }
    },

#5

The key is that helpers are called multiple times during the Template lifecycle, and when data isn’t present yet errors like these occur.

I have started to religiously subscribe in Template.onCreated and then check if Template.subscriptionsReady before accessing any data. This will mess with any jQuery stuff you might put into Template.onRendered, which I solve with sub-templates

Something like this

<template name="template">
 {{#if Template.subscriptionsReady}}
   {{>templateData data=helperFunction}}
 {{else}}
   Waiting for subscriptions ...
 {{/if}}
</template>

<template name="templateData">
 ...
</template>