Backbone.js Empty Array Attribute
arrays, backbone.js, javascript
Solution
Be careful about trusting the console, there is often asynchronous behavior that can trip you up.
You're expecting `console.log(x)` to behave like this:
- You call `console.log(x)`.
- `x` is dumped to the console.
- Execution continues on with the statement immediately following your `console.log(x)` call.
But that's not what happens, the reality is more like this:
- You call `console.log(x)`.
- The browser grabs a reference to `x`, and queues up the "real" `console.log` call for later.
- Various other bits of JavaScript run (or not).
- Later, the `console.log` call from (2) gets around to dumping the current state of `x` into the console but this `x` won't necessarily match the `x` as it was in (2).
In your case, you're doing this:
console.log(this.attributes);
console.log(this.attributes.widgets);
So you have something like this at (2):
attributes.widgets
^ ^
| |
console.log -+ |
console.log -----------+
and then something is happening in (3) which effectively does `this.attributes.widgets = [...]` (i.e. changes the `attributes.widget` reference) and so, when (4) comes around, you have this:
attributes.widgets // the new one from (3)
^
|
console.log -+
console.log -----------> widgets // the original from (1)
This leaves you seeing two different versions of `widgets`: the new one which received something in (3) and the original which is empty.
When you do this:
console.log(_(this.attributes).clone());
console.log(_(this.attributes.widgets).clone());
you're grabbing copies of `this.attributes` and `this.attributes.widgets` that are attached to the `console.log` calls so (3) won't interfere with your references and you see sensible results in the console.
That's the answer to this:
It's showing that widgets is not empty when logging `this.attributes` but it's shown as empty when logging `this.attributes.widgets`. Does anyone know what would cause this?
As far as the underlying problem goes, you probably have a `fetch` call somewhere and you're not taking its asynchronous behavior into account. The solution is probably to bind to an `"add"` or `"reset"` event.
Problem
I'm running into an odd issue with a Backbone.js Model where an array member is being shown as blank. It looks something like this: ``` var Session = Backbone.Model.extend({ defaults: { // ... widgets: [] }, addWidget: function (widget) { var widgets = this.get("widgets"); widgets.push(widget); this.trigger("change:widgets", this, widgets); }, // ... // I have a method on the model to grabbing a member of the array getWidget: function (id) { console.log(this.attributes); console.log(this.attributes.widgets); // ... } }); ``` I then add a widget via `addWidget`. When trying `getWidget` the result I get (in Chrome) is this: ``` Object widgets: Array[1] 0: child length: 1 __proto__: Array[0] __proto__: Object [] ``` It's showing that widgets is not empty when logging `this.attributes` but it's shown as empty when logging `this.attributes.widgets`. Does anyone know what would cause this? EDIT I've changed the model to instantiate the widgets array in the initialization method to avoid references across multiple instances, and I started using backbone-nested with no luck.