Having difficulty accessing attributes within the template - encountering errors for all attributes except for 'name', stating '[attributename] is not defined'

There seems to be an issue with accessing Object attributes other than 'name' in the template. When trying to access attributes like id or url, errors such as 'id/url/whatever is not defined' are logged in the console. The JSON file passed to the view contains all items at the same level and can be accessed from the console using methods like

collectionName.models[0].get('id');

The behavior where 'name' attribute works correctly suggests that it might be predefined within backbone/underscore code as a default.

I am puzzled by this behavior. Since I am able to access model data from the console, it indicates that there could be an issue with how the view handles the data itself. Despite trying various approaches to rewrite the code, nothing seemed to resolve the problem.


Here is the relevant code:

Format of the passed object. This output is also returned when running

collectionName.models[0].attributes;
in the console.

[{
"id":"0",
"name": "Building1",
"url": "building_1",
"floors":[{
    "id":"0",
    "name":"Ground Floor",
    "image":"",
    "rooms":[{
        "id": "r_1",
        "name": "Room 1",
    },
    {
        "id": "r_2",
        "name": "Room 2"
    }]
}
}]

}

Sample template code:

<span class="name"><%= name %></span>
<%= id %> <%= url %>

The router code:

routes: {
  '': 'intro', // this route is using pretty much identical code and works fine, the model has the exact same format, the only difference is that all attributes work.
  ':id': 'firstLevel'    
},

firstLevel: function (id) {
  window.singleBuilding = new ThisBuilding({}, {idBuilding: id});

  window.singleBuilding.fetch();      

  this.floorView = new FloorList({
    collection: window.singleBuilding
  });

  var $intro = $('#intro');
  $intro.empty();
  $intro.append(this.floorView.render().el);
}

Views:

window.FloorSingleList = Backbone.View.extend({

  className: 'floor-list',

  initialize: function () {

  this.template = _.template(tpl.get('floors-list-item')); 
  _.bindAll(this, 'render');
  this.model.bind('change', this.render);
  this.testModel = this.model.attributes; 
},

render: function() {
  console.log("The test data is:", this.testModel);
  console.log("The actual model data is:", this.model);
  var renderedContent = this.template(this.model.toJSON());
  $(this.el).html(renderedContent);

  return this;
 }

});

window.FloorList = Backbone.View.extend({

tagName: 'section',
className: 'intro-list',

initialize: function () {

  this.template = _.template(tpl.get('intro-list'));
  _.bindAll(this, 'render');
  this.collection.bind('reset', this.render, this);
  this.collection.bind('change', this.render, this);
},

render: function(eventName) {

     var $introList;
     var collection = this.collection;

  $(this.el).html(this.template({ }));
  $introList = this.$('.intro-list');
  collection.each(function(building) {
    var view = new FloorSingleList({
      model: building,
      collection: collection
    });
    $introList.append(view.render().el);
  });

  return this;
}

});

Model code:

window.ThisBuilding = Backbone.Collection.extend({

model: Building,

initialize: function(models, options) {
  // Initializing the argument passed on from the router.
  this.idBuilding = options.idBuilding;
  return this;
},

url: function(){
  return "data.json";     
},

parse: function(response) {
  console.log("Passed parameters are :", this.idBuilding); 
  return response[this.idBuilding];
}

});

Templates & Bootstrap

// templates are loaded during the bootstrap 
tpl.loadTemplates(['header', 'intro-list', 'floors-list-item', 'building-list-item'], function() {
    window.App = new ExampleApp();
    Backbone.history.start();
});

Answer №1

One of the issues lies in the asynchronous nature of the fetch function in JavaScript...

firstLevel: function  (id) {
  window.singleBuilding = new ThisBuilding({}, {idBuilding: id});

  window.singleBuilding.fetch();  // FETCHING OPERATION

  this.floorView = new FloorList({
    collection: window.singleBuilding
  });

  var $intro = $('#intro');
  $intro.empty();
  $intro.append(this.floorView.render().el); // RENDERING WITHOUT CHECKING IF FETCH HAS COMPLETED
}

This approach can lead to rendering incomplete data because the models may not have been fully fetched yet. To resolve this, consider the following:

firstLevel: function  (id) {
  window.singleBuilding = new ThisBuilding({}, {idBuilding: id}); 

  // Avoid fetching here...

  this.floorView = new FloorList({
    collection: window.singleBuilding
  });

  var $intro = $('#intro');
  $intro.empty();
  $intro.append(this.floorView.el); // Defer rendering
}

In the FloorList-view, modify the initialize function as follows:

initialize: function () {

  this.template = _.template(tpl.get('intro-list'));
  _.bindAll(this, 'render');
  this.collection.bind('reset', this.render, this);
  this.collection.bind('change', this.render, this);
  this.collections.fetch(); // Perform fetch here, rendering is managed by event bindings
}

Update 2: Disregard Previous Complexity Observations

Referencing the Backbone.js documentation regarding Model.toJSON():

The method returns a serialized JSON representation of the model's attributes.

This means that only attributes are included, while properties like id and url reside separately within the model object. It could be structured like this:

{
  ...
  attributes: Object // Attributes stored here (e.g., name)
  ...
  id: 34, // Id property separate from attributes
  ...
  __proto__: ctor, // Url function resides here
  ...
}

UPDATE: Ensure id-property inclusion in model.toJSON()

When employing this.model.toJSON(), ensure that the id property is manually added if necessary, as it is not automatically included in the serialization alongside other attributes. For instance:

var renderedContent = this.template({
  attributes: this.model.toJSON(),
  url: this.model.url()
});

Within the template:

<span class="name"><%= attributes.name %></span>
<%= attributes.id %> <%= url %>

These adjustments should provide clarity on handling model data effectively!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Accessing ExpressJS from AngularJS through local server

My latest project involves building a Web Application using AngularJS and ExpressJS. In this application, I have set up a GET "/" route in my app.js file to render the index.html page when accessed. One interesting feature is the GET "/test-data" route in ...

How to insert an image into a placeholder in an .hbs Ember template file

I'm looking to enhance a .hbs template file in ember by incorporating an image. I am not a developer, but I'm attempting to customize the basic todo list app. <section class='todoapp'> <header id='header'> & ...

Nextjs server encountered an issue where it was unable to connect to the localhost

npm run dev > <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="563239352239247b372626393f38223b3338227b3439393d3f38317b2133347b372626166678677866">[email protected]</a> dev > next dev ▲ Next.js 14.2. ...

Attempting to modify the element's value with the help of selenium

I am facing an issue while trying to change the element through Selenium. Despite using send keys and execute_script, the value remains unchanged. I am attempting to set the value to 'R'. driver.find_element_by_name('wlw-select_key:{actionF ...

Issue with exporting Three.js to Maya

I've been attempting to utilize the Three.js exporter for Maya found here. However, when I try to load the threeJsFileTranslator.py plug-in from the plug-ins manager in Maya, I encounter an error in the Script Editor: // Error: line 1: invalid synta ...

Discover the unique value in Angular if it is not present in the list

I have a question about handling values in a list and displaying the "create value" component to the user when needed. How can I efficiently compare search input values with those in the list and determine if a match exists? If no match is found, the "cr ...

Next.js Error: The text displayed on the page differs from the HTML rendered by the server

Currently, I am facing an issue with the error "Error: Text content does not match server-rendered HTML." Here is my scenario - I have received a dateTime from an API, for example '2022-12-25T11:22:37.000Z', and I want to display it on a compone ...

Guide on retrieving data from an axios promise in JavaScript

I am struggling to manage the output of multiple lists retrieved through an axios API call made in JavaScript. I want to know how to effectively log the results and save them for future use, particularly for creating a data visualization. Here is my curre ...

I have a json file that I need to convert to a csv format

I am currently working with a json file, but I need to switch it out for a csv file. Do I have to use a specific library to accomplish this task, or can I simply modify the jQuery 'get' request from json to csv? I attempted the latter approach, b ...

Is there a method to hide an HTML form completely?

Is there a way to quickly hide an HTML form from a webpage once the submit button is clicked and replace it with the result of a .php file in the most efficient manner possible, with minimal code? ...

Returning draggable elements to their original placement

I'm looking to create a custom function that resets my draggable elements to their original positions when invoked. This is not related to the built-in revert functionality. $('.drag').draggable({ stack: ".drag", snap: ".dro ...

The functionality for transferring ERC20 claim tokens seems to be malfunctioning

I am facing an issue with my contract while trying to execute the claimFreeToken function. Even though the contract does not have enough tokens, the function does not return an error and the token also does not get received. Can anyone point out where I ...

Attach an event listener to a class, then use the removeEventListener method to detach the listener and eliminate any remaining references, ensuring proper functionality of the

When creating a class in JavaScript, a normal function returns the class object. However, events return the event object and the class object is lost: function class(a){ this.name=a; document.addEventListener('click',this.click,false); xhr.add ...

What is the proper way to incorporate the "pdf" package into a TypeScript project?

I recently installed pdf and its types using the following command: npm install --save pdf @types/pdf However, I am struggling to find any documentation on how to actually use this package. When I try the following code: import {PDFJS} from 'pdf&ap ...

Discovering the initial word of a string using jQuery

I'm currently facing an issue with jQuery that I need help solving. Here's the scenario: I am creating tooltips and positioning them directly under a specific trigger using CSS. Everything is functioning correctly, but there is one problem: In ...

A guide on updating a MySQL table using a JSON object in Node.js

I have a JSON Object and need to UPDATE a mySQL table without listing all of the keys individually For an INSERT operation, I use the following code: var arrayValue = Object.keys(obj).map(function(key) { return String("'"+obj[key]+"'"); ...

Unable to make a post using vue.js

I am facing an issue while trying to submit form data using "vue-resource" in my code. The error message I receive mentions a problem with the use of this method alongside vue-cli and vuetify. Error [Vue warn]: Error in v-on handler: "TypeError: this.$h ...

What is the preferred default value for a property awaiting assignment from a GET response: Undefined or Null?

Say I need to display information about a product, but first I must make a GET request to get the data and assign it to the product. I'm wondering, should the default value for product in the data() function be undefined or null, and is there a differ ...

When a div is modified through an ajax function, I aim to activate a JavaScript function

Is there a way to automatically execute a javascript function once the status updates to "Upload successful"? I am uncertain about how to accomplish this task. Following a multi file upload, the status will switch based on whether it was successful or en ...

Adding the number of occurrences to duplicates in a string array using JavaScript

Looking to append a count to duplicate entries within a string array. The array in question contains duplicates, as shown below. var myarray = ["John", "John", "John", "Doe", "Doe", "Smith", "John", "Doe", "Joe"]; The desired output shoul ...