1

I am just starting to learn the Modular Design principles and I believe I am not understanding the context of one of my methods. In the console, I am getting Uncaught TypeError: Cannot read property 'val' of undefined - line 19. I am using Firebase, if that matters.

Here is my code:

(function(){
    var UpdateTable = {
        resources: Resources,
        init: function(){
            this.cacheDom();
            this.render();
            this.update(snapshot); // Changed this line ///
        },
        render: function(){
            this.resources.on('value', this.update);
        },
        cacheDom: function(){
            this.$table = $('#resourceTable');
        },
        update: function(snapshot){
            console.log(snapshot.val());
            for(var resource in this.resources){
                this.$table.append('<tr><td>' + this.resources[resource].name + '</td><td>' + this.resources[resource].language + '</td></tr>');
            }
        }
    };
    UpdateTable.init();
})();
dericcain
  • 2,182
  • 7
  • 30
  • 52

2 Answers2

1

If you want to make this truly modular, I suggest to pass snapshot as a parameter for your module. This will fix your issue.

(function(snapshot){ // <----- Here I receive snapshot from the invoker
    var UpdateTable = {
        resources: Resources,
        init: function(){
            this.cacheDom();
            this.render();
            this.update(snapshot); // Changed this line ///
        },
        render: function(){
            this.resources.on('value', this.update);
        },
        cacheDom: function(){
            this.$table = $('#resourceTable');
        },
        update: function(snapshot){
            console.log(snapshot.val());
            for(var resource in this.resources){
                this.$table.append('<tr><td>' + this.resources[resource].name + '</td><td>' + this.resources[resource].language + '</td></tr>');
            }
        }
    };
    UpdateTable.init();
})(snapshot); // <---- Here I am passing snapshot from global context to the module context
Tiago Romero Garcia
  • 1,068
  • 9
  • 11
  • I apologize for not understanding this, but I used that exact code and I am getting an error on the last line saying `Uncaught ReferenceError: snapshot is not defined`. I made a Codepen here: http://codepen.io/dcain19/pen/MaveqE – dericcain Oct 11 '15 at 22:20
  • So this means that you actually need to provide ```snapshot``` somewhere in the global context. – Tiago Romero Garcia Oct 11 '15 at 22:22
  • Just to illustrate, please add this right before the module: var snapshot = $(document); – Tiago Romero Garcia Oct 11 '15 at 22:23
  • Then, this var will be passed to your module, through a parameter, therefore truly encapsulating its value within the module. – Tiago Romero Garcia Oct 11 '15 at 22:24
  • I did that, and of course, it says `undefined` in the console, but it does not give me an error. If I create and empty variable, I get an error in the console. Thanks for the help! Now, I have to go and learn more about this so I can understand it better. – dericcain Oct 11 '15 at 22:42
  • You welcome! By looking at your code it looks like ```snapshot``` should be some element in the DOM wrapped in a jQuery selector, probably an `````` tag since you are doing ```snapshot.val()``` inside ```update()```. I hope this helps! – Tiago Romero Garcia Oct 11 '15 at 22:44
  • Here is where I am getting the code to do what I am trying to do: https://www.dropbox.com/s/f9rofhc3uhzcmj4/Screenshot%202015-10-11%2018.47.28.png?dl=0 I am just not understanding how to use this in my module. – dericcain Oct 11 '15 at 22:45
0

You specify that update should take an argument - shapshot - but aren't passing it in init(). When you given a function an argument it is an implicit variable declaration.

var args = 1;
function f(args) {
    console.log(args);
}

f();
// => 'undefined'

Instead you want:

var args = 1;
function f() {
    console.log(args); // args now looks to the outer scope
}

f();
// => 1

Or

var args = 1;
function f(args) {
    console.log(args); 
}

f(args);  // args is explicitly passed in
// => 1
Jonah Williams
  • 20,499
  • 6
  • 65
  • 53
  • @JonahWillams I updated the code in my question but now I am getting `Uncaught ReferenceError: snapshot is not defined`. I don't quite understand where I am going wrong. – dericcain Oct 11 '15 at 22:08
  • where is snapshot? your error is due to the fact that snapshot is not available to any parent scopes – Jonah Williams Oct 11 '15 at 22:10