views:

61

answers:

2

i have two files

one called stats.js

one called storage.html

in stats.js in contains

var stats = {
  myFunc : function() {
    //do something
  }
}

in storage.html I have

<html>
<head>
<script src="stats.js"></script>
<script>
$(document).ready(function() {
   stats.myFunc(); 
});
</script>
</head>
</html>

But I get

Uncaught TypeError: Cannot call method 'myFunc' of undefined


Update
Ok so that was a really simplified example.

The basics of it are,

This is a google chrome extension, So you will see some code specific to that.

Here is the literal pages concerned:

Popup.html

<html>
    <head>
        <title>Extension</title>
        <script src="http://code.jquery.com/jquery-1.4.2.min.js"&gt;&lt;/script&gt;
        <script src="js/popup.js"></script>
        <script src="js/statsapi.js"></script>
        <link type="text/css" rel="stylesheet" href="css/popup.css" />
    </head>
    <body>
        <div id="content">
        </div>
    </body>
</html>

popup.js

$(document).ready(function() {
    if(background.storage.get('firstRun') == null)
        background.initialize();

    if(background.storage.get('metaExpire') >= Date.parse(Date()))
        background.updateMeta();

    $('#content').append(read_object(stats.getMetaData()));
});

function read_object(object){
    var $obj = $('<div />');
    for(var o in object) {
        $obj.append(o+' : ');
        if(typeof(object[o]) == 'object' && object[o] != null)
            $obj.append(read_object(object[o]));
        else
            $obj.append(object[o]+'<br />');
    }
    return $obj;
}

Manifest.json

{
  "name": "Halo Reach: Stats",
  "description": "This extension allows you to keep track of your own, and your friends Halo Reach Stats.",
  "version": "1.0.0.1",
  "permissions": [
    "http://www.bungie.net/"
  ],
  "icons": { 
      "128": "images/logo/logo128.jpg",
      "64": "images/logo/logo64.jpg",
      "32": "images/logo/logo32.jpg",
      "16": "images/logo/logo16.jpg"
  },
  "browser_action": {
    "default_title": "Open Stats",
    "default_icon": "images/logo/logo32.jpg",
    "popup": "popup.html"
  },
  "background_page": "background.html"
}

statsapi.js

var background  = chrome.extension.getBackgroundPage();
var apikey      = background.storage.get('apikey');
var gamertage   = background.storage.get('gamertag');
var page        = '0';

var stats = {
    getMetaData : function() {
        var url = 'http://www.bungie.net/api/reach/reachapijson.svc/game/metadata/'+apikey;
        console.log(url);
        $.ajax({
            url: url,
            success: function(data) {
                return data;
            }
        });
    },

    meta : {
        read : function(param) {
            var meta = background.storage.get('metaData');
        }
    }
};

Background.html

<html>
    <head>
        <script src="js/statsapi.js"></script>
        <script>
            var storage = {
                set : function (key, value) {
                    window.localStorage.removeItem(key);
                    window.localStorage.setItem(key, value);
                },            
                get : function (key) {
                    return window.localStorage.getItem(key);
                },            
                clear : function () {
                    window.localStorage.clear();
                }
            };

            function updateMeta() {
                var meta = stats.getMetaData();
                if(meta['status'] == 0){
                    storage.set('metaData', JSON.stringify(meta));
                    storage.set('metaExpire', Date.parse(Date())+900000);
                }
            }

            function initialize() {
                storage.set('apikey', '***');
                storage.set('gamertag', 'The Hailwood');
                updateMeta();
            }
        </script>
    </head>
</html>

When the extension is invoked it calls popup.html

and the document ready javascript is invoked.

The check for first run fails,

so it calls initialize() in background.html

But this is where the error occurs.

the actual error is

Uncaught TypeError: Cannot call method 'getMetaData' of undefined.

So why can it not see the stats class?

its not a script include problem as if the path is wrong for the statsapi.js I get

Uncaught ReferenceError: stats is not defined.

The issue seems to be with the var stats {} as if under that I have a function called test() I can call that fine :/

Hmm,

is there an issue because it is an external stylesheet?

+1  A: 

I suspect the error lies somewhere else - these are my examples:

mark@localhost:~/ccsite$ cat cat.js 
var stats = {
  myFunc : function() {
    alert('wtf');
  }
}


mark@localhost:~/ccsite$ cat hat.htm 
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"&gt;&lt;/script&gt; 
<script src="cat.js"></script>
<script>
$(document).ready(function() {
   stats.myFunc(); 
});
</script>
</head>
</html>

Viewing hat.htm in either FF, IE6 or Chrome produces the alert, 'wtf'. As written you'd get $ is undefined, since it's not including jQuery of course, so I added that.

So, your problems likely are elsewhere. I assume this is a simplified example - what else is going on in your page?

Mark Snidovich
I have updated the code.
Hailwood
A: 

I have suspicions that it's because you include js/statsapi.js script into both your popup and background page, so it gets confused which stats you are referring to as you have 2 of them in the popup - one included through script tag and another one loaded from background page after you call chrome.extension.getBackgroundPage()

serg
nope, I need to include it separately in the background page as all calls to that are independent of the popup page.
Hailwood