views:

106

answers:

3

I'm having a bit of an issue with my javascript object. What I want to do is pass in an id and have it set a variable that is accessible to all of my functions.

Here's a small sample of what I have:

var myObject = function() {
    var pageSize = 6;
    var currentPage = 1;
    var pagerPagesVisible = 5;
    var pagerId = '#my-pager';
    var entityId = '';

    var doStuff = function() {

        var endIndex = pageSize * currentPage;
        var startIndex = endIndex - pageSize;

        $.ajax({ type: "GET", url: "/items/" + this.entityId + "/entities/" + startIndex + "/" + pageSize + "/", dataType: "json", success: loadData, cache: false,
            error: function(response, status, error) {
                alert(response.responseText);
            }
        });

    };

    var loadData = function(data) {
        var itemCount = data.length;

        //build the html and write to the page

        buildPager(itemCount);
    };


    var buildPager = function(itemCount) {

        pager.build(pagerId, pageSize, itemCount, currentPage);

    };

    var attachEvents = function() {
        //attach events to the pager
    };

    return {

        init: function(entityId) {
            this.entityId = entityId;

            doStuff();
        }
    }
} ();

the issue is, in init, it sets the entityId instance that you see at the top. But when it hits doStuff() entityId is set back to ''.

+1  A: 

You're mixing closure and object styles - you need to be consistent:

<script>

var myObject = function() {
    var pageSize = 6;
    var currentPage = 1;
    var pagerPagesVisible = 5;
    var pagerId = '#my-pager';
    var entityId = '';

    var doStuff = function() {
     alert(entityId);
    };

    return {

        init: function(myEntityId) {
            entityId = myEntityId;

            doStuff();
        }
    }
} ();

myObject.init(123);

</script>
Greg
changing the name of the input parameter did the trick Thanks.
Josh
A: 

That's because the entityId variable is local to the function and has nothing to do with the object you create at the end. Instead, put everything in that object at the end and not as locals in the function.

eg.

var myObject = function() {
  var pageSize = 6;
  var currentPage = 1;
  var pagerPagesVisible = 5;
  var pagerId = '#my-pager';

  return {
    doStuff: function() {
      var endIndex = pageSize * currentPage;
      var startIndex = endIndex - pageSize;
      var self = this;

      $.ajax( {
        type: "GET",
        url: "/items/" + this.entityId + "/entities/" + startIndex + "/" + pageSize,
        dataType: "json",
        success: function() { self.loadData(); },
        cache: false,
        error: function(response, status, error) {
          alert(response.responseText);
        }
      } );
    },
    loadData: function(data) {
      var itemCount = data.length;
      this.buildPager(itemCount);
    },
    buildPager = function(itemCount) {
      pager.build(pagerId, pageSize, itemCount, currentPage);
    },
    attachEvents: function() {
      //attach events to the pager
    },
    entityId: '',
    init: function(entityId) {
      this.entityId = entityId;
      this.doStuff();
    }
  };
}();
thenduks
You've made all the private methods public by doing that
Greg
Yes. Is that a problem? Everything is public in JavaScript, fwiw. This is just to show the scoping problem in the question. If there was a concern with private methods then those methods could be moved out of the object with no trouble at all. Worst case you just need to pass some extra stuff to them from inside the public methods. I don't see how this makes my answer wrong.
thenduks
@thenduks Saying everything in JavaScript is public is ... generally true. But, a bit misleading. If someone said that to me about a language, it would suggest that there is no encapsulation at all, all variables and properties are public. But that is not the case in JavaScript. You can get private functions and variables through the use of closures - http://www.crockford.com/javascript/private.html
Matt
What I mean is that this isn't Java or something where you can prevent users of your library from accessing private methods. A user can do whatever they like with your JavaScript code and as a result, in practice, it's pretty pointless to bother worrying about making things private. Besides the fact that most (and this, specifically) of the code is heavily tied to the page it's used on... it hardly matters.
thenduks
A: 

Others have answered your question here, but I wanted to point out that you may want to use the prototype if you are going to be creating many of these objects.

When you enclose your methods you waste memory on every instantiation.

ClassName.prototype.methodname = function(){ ... }
Tim