0

First let me preface this question by saying that I'm fairly new to Javascript.

I also understand that Javascript objects are passed by reference and primitives are passed by value [source].

That said, here's my question (simplified example): I'm pulling in JSON data that contains a lot of different information and I need to put each different type of information into a <ul> that's in another <ul> like this:

<ul class="car-tree">
  <li>
    <label>Sports Cars</label>
    <ul class="sport-cars">
      <li>Porsche</li>
      <li>Mercedes</li>
      <li>BMW</li>
    </ul>
  </li>
  <li>
    <label>Super Cars</label>
    <ul class="super-cars">
      <li>Ferrari</li>
      <li>Lamborghini</li>
    </ul>
  </li>
  <li>
    <!-- and so on... -->
  </li>
</ul>

I'm grabbing a template for the list above that contains everything except the inner most <li> tags and I'm trying to populate it like this:

var CarView = function(){

  var buildCarTree = function(){

    // Gets the JSON data from somewhere
    var jsonData = grabJsonData();

    // Grab the template and convert it into a jQuery object
    var template = $(grabCarTreeTemplate());

    // Adds sport car data to sports cars list
    this.addCars(template.find('.sports-cars'), jsonData.sportsCars);

    // Adds super car data to sports cars list
    this.addCars(template.find('.super-cars'), jsonData.superCars);

    // Add the car tree to some container
    $('#container-trees').append(template);
  }

  var addCars = function(container, carData){

    for(id in carData){
      $('<li/>', {
        text : carData[id].text
      }).appendTo(container);
    }
  }
};

var view = new CarView();
view.buildCarTree();

When you do this you get the template without the data being added in, although, if you add in console.log statements through out addCars you can see the data being added to the container argument.

I'm confused because from what I understand from the source I provided above:

...if you change the parameter itself...that won't affect the item that was fed into the parameter. But if you change the INTERNALS of the parameter, that will propagate back up...

and I would have figured that appendTo would be changing the internals of the jQuery object. What's the deal?

Community
  • 1
  • 1
Steve
  • 1,112
  • 8
  • 12
  • Is `grabJsonData` making an ajax request? If so, you have async issues. Post the contents of `grabJsonData` and I'll show you how to fix. – glortho Jan 12 '12 at 21:22
  • No that's not the problem. The JSON part isn't important because I can see the lists being modified correctly inside addCars, but when I leave that function, the list doesn't reflect those modifications. – Steve Jan 12 '12 at 21:24

1 Answers1

1

It looks like you're trying to call private var functions as if they were methods of the obj. Change to this and try:

var CarView = function(){

  this.buildCarTree = function(){

    // Gets the JSON data from somewhere
    var jsonData = grabJsonData();

    // Grab the template and convert it into a jQuery object
    var template = $(grabCarTreeTemplate());

    // Adds sport car data to sports cars list
    this.addCars(template.find('.sports-cars'), jsonData.sportsCars);

    // Adds super car data to sports cars list
    this.addCars(template.find('.super-cars'), jsonData.superCars);

    // Add the car tree to some container
    $('#container-trees').append(template);
  }

  this.addCars = function(container, carData){

    for(id in carData){
      $('<li/>', {
        text : carData[id].text
      }).appendTo(container);
    }
  }
};

var view = new CarView();
view.buildCarTree();

EDIT: See this jsFiddle for working code: http://jsfiddle.net/eHrH6/

glortho
  • 13,120
  • 8
  • 49
  • 45
  • Correct you are! Now I feel silly for overlooking that...boy do I miss pair-programming! – Steve Jan 13 '12 at 02:23