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

Proceed with another ajax request only when the previous one has been successfully completed and loaded

While scrolling down and loading content into my page, I am facing an issue. The ajax executions load too quickly, causing the subsequent calls to not receive correct information from the first ajax call that is loaded into the DOM. How can I ensure that ...

How to set a timeout for a socket.io connection in a node.js application

After searching through the documentation, I couldn't find a specific solution for expiring or disconnecting a socket.io client after a certain period of time. I am seeking a workaround that is both manageable and asynchronous in node.js. One possibl ...

Utilize the HTTP path to designate the currently active tab

Here is a sample code snippet for vertical tabs in React using the Material-UI library: import * as React from 'react'; import Tabs from '@mui/material/Tabs'; import Tab from '@mui/material/Tab'; import Typography from '@ ...

Stop the upload progress in Angular 6 by unsubscribing from the upload observable, without halting the actual

When attempting to cancel an upload by unsubscribing, the unsubscribe action only stops the progress of the upload from being displayed, but the actual upload process continues and files are still uploaded to the server. This issue is present in the upload ...

How can you achieve the effect of "hovering over an image to automatically start playing a muted video within the image itself"?

[![enter image description here][1]][1]I am working with WordPress and Elementor, and I want to create a hover effect where an image triggers a muted video to play within the image area on mouseover. The video should stop playing when the mouse is not hove ...

Vue-powered carousel having trouble rotating properly

I recently came across a carousel created using vanilla javascript and html. I attempted to convert it to Vue, but encountered some challenges. The carousel is supposed to dynamically pull images from a SharePoint list. However, in my version, the images a ...

For Firefox, the status code always comes back as 0 when using xmlhttprequest

When attempting to make asynchronous calls using the xmlhttprequest object, everything functions perfectly in Internet Explorer. However, Firefox seems to be encountering issues. Here is a snippet of the problematic code: if (req.readyState == 4) { i ...

Eliminate the selected item at random

I'm looking for a way to remove the randomly picked item from my namepicker so that it doesn't appear twice. const Names = [ { name: 'Name1', id: 1 }, { name: 'Name2', id: 2 }, ] btnClick = () => { let ...

Unable to retrieve data from response using promise in Angular 2?

I am struggling to extract the desired data from the response. Despite trying various methods, I can't seem to achieve the expected outcome. facebookLogin(): void { this.fb.login() .then((res: LoginResponse) => { this.acce ...

Fixing the department display list in React Hook: A step-by-step guide

{ roomDept.map((item, index) => ( <div key={index} className="flex flex-col pb-2 items-center"> <div className="flex pb-2 w-full"> <SelectPick ...

Make sure to include the onBlur and sx props when passing them through the slotsProp of the MUI DatePicker

This DatePicker component is using MUI DatePicker v6. /* eslint-disable no-unused-vars */ // @ts-nocheck import * as React from 'react'; import { Controller } from 'react-hook-form'; import TextField from '@mui/material/TextField&a ...

Tips on customizing the appearance of two Material-UI Sliders across separate components

Looking to customize two sliders, each within their own react component. Slider in the first component const customizedThemeSlider1 = createTheme({ overrides:{ MuiSlider: { thumb:{ color: "#4442a9", marg ...

Unable to scroll after the webpage redirects

I am currently working on developing a website for uploading images with a comment feature. The comments section is displayed below the image in the 'imagedisplay.php' file. If a user is not logged in, they are redirected to the sign-up page and ...

How to access iFrame in ReactJS using document.getElementById

I am facing a challenge on my website where I need to transfer data (using postMessage) to an iframe. Typically in plain JavaScript, I would use techniques like document.getElementById or $("#iframe") in jQuery to target the iframe. However, I am unsure ...

Trouble with Callback firing in Select2's 'Infinite Scroll with Remote Data' feature

After reviewing the tutorial on the Select2 project page, I am implementing a feature to load additional records as the user scrolls to the end of the results. <script> $(document).ready(function() { $('#style_full_name').select2({ ...

Struggling to integrate a functional update button into my Material UI datagrid version 5.6.1

I'm facing a challenge in adding a button to the rows of my Material UI DataGrid component. Here is my DataGrid component setup: <DataGrid rows={adminStorage} columns={columns} autoPageSize getRowId={(logistics) => logistics._id ...

"Encountered a TypeError: Cannot read property 'params

I've encountered an issue with passing the id to my product page. Despite trying various solutions and searching for answers, I still can't get it to work. Below is my index.js code: import React from "react"; import {render} from &quo ...

Discover the HTML of a different website using Javascript

I'm currently developing a basic webcrawler that will display all the links found on a specified website. Here's what I envision my program doing: - enter a URL: http://www.example.com/ - the program retrieves the HTML source and locates all th ...

Switch up your code and toggle a class on or off for all elements that share a specific class

I've been attempting to create a functionality where, upon clicking a switch, a specific class gets added to every element that is assigned the class "ChangeColors". Unfortunately, I have encountered some difficulties in achieving this task. The error ...

Activate the Keypress event to update the input value in React upon pressing the Enter

I am facing an issue where I need to reset the value of an input using a method triggered by onPressEnter. Here is the input code: <Input type="text" placeholder="new account" onPressEnter={(event) => this.onCreateAccount(event)}> < ...