caramba
caramba

Reputation: 22480

Dynamically setting values to an array of objects in Javascript

How can I get this to work?

Trying to set an array of blocks containing block objects...

var blocks = [];
var block  = {
  type: null,
  color: null
};

var dom_blocks = document.querySelectorAll('.block');

for( var i= 0, ii = dom_blocks.length; i < ii; i++) {
  blocks[i] = Object.create(block);
  blocks[i].block = dom_blocks[i].dataset.type;        // this kills my object
  blocks[i].block.color = dom_blocks[i].dataset.color; // this ain't working
}

console.log(blocks);
<div class="block" data-type="false" data-color="red"></div>
<div class="block" data-type="true"  data-color="green"></div>
<div class="block" data-type="true"  data-color="orange"></div>
<div class="block" data-type="false" data-color="fuchsia"></div>

<script src="https://getfirebug.com/firebug-lite-debug.js"></script>

Update What I'm trying to achieve is to iterate over the HTML <div class="block"> and write it to Javascript Objects which I'll need to manipulate later.

The desired end would be an array blocks[] containing the data from each block in an object.

Upvotes: 0

Views: 69

Answers (2)

T.J. Crowder
T.J. Crowder

Reputation: 1074295

This line:

 blocks[i].block = dom_blocks[i].dataset.type;

relies on the browser supporting dataset, which isn't universally supported yet. On browsers that do, it will set blocks[i].block to a string ("true" or "false"). For older browsers, you can use getAttribute:

 blocks[i].block = dom_blocks[i].getAttribute("data-type");

(BTW, perhaps you meant .type = rather than .block =?)

This line:

blocks[i].block.color = dom_blocks[i].dataset.color;

doesn't do anything, because you're setting a property color on a primitive string. When you do that, the string is promoted to an object briefly, but then that object is thrown away and this becomes a no-op.

So if things are "blowing up" it sounds like you're using a browser that doesn't support dataset. Otherwise, you just need to do something else with color.

Finally, there's no point in using block as a prototype if you're just going to assign its only properties to instances anyway.

If you wanted to set color on blocks[i] instead of blocks[i].block, e.g.:

blocks[i].color = dom_blocks[i].dataset.color;

...it'll work (on browsers supporting dataset):

var blocks = [];
var block  = {
    type: null,
    color: null
};

var dom_blocks = document.querySelectorAll('.block');

for (var i= 0, ii = dom_blocks.length; i < ii; i++) {
    blocks[i] = Object.create(block);
    blocks[i].block = dom_blocks[i].dataset.type;
    blocks[i].color = dom_blocks[i].dataset.color;
}

console.log(blocks);
.as-console-wrapper {
    max-height: 100% !important;
}
<div class="block" data-type="false" data-color="red"></div>
<div class="block" data-type="true"  data-color="green"></div>
<div class="block" data-type="true"  data-color="orange"></div>
<div class="block" data-type="false" data-color="fuchsia"></div>

Or for older browsers:

var blocks = [];
var block  = {
    type: null,
    color: null
};

var dom_blocks = document.querySelectorAll('.block');

for (var i = 0, ii = dom_blocks.length; i < ii; i++) {
    blocks[i] = Object.create(block);
    blocks[i].block = dom_blocks[i].getAttribute("data-type");
    blocks[i].color = dom_blocks[i].getAttribute("data-color");
}

console.log(blocks);
.as-console-wrapper {
    max-height: 100% !important;
}
<div class="block" data-type="false" data-color="red"></div>
<div class="block" data-type="true"  data-color="green"></div>
<div class="block" data-type="true"  data-color="orange"></div>
<div class="block" data-type="false" data-color="fuchsia"></div>

Upvotes: 1

Jose Rui Santos
Jose Rui Santos

Reputation: 15319

Use the cross-browser getAttribute() and simplify things by creating the object directly in the push.

There is no need to explicitly call the Object.create()

var blocks = [],
    dom_blocks = document.querySelectorAll('.block');

for(var i= 0, ii = dom_blocks.length; i < ii; i++) {
  blocks.push({
    type: dom_blocks[i].getAttribute('data-type'),
    color: dom_blocks[i].getAttribute('data-color')
  });
}

console.log(blocks);
<div class="block" data-type="false" data-color="red"></div>
<div class="block" data-type="true"  data-color="green"></div>
<div class="block" data-type="true"  data-color="orange"></div>
<div class="block" data-type="false" data-color="fuchsia"></div>

<script src="https://getfirebug.com/firebug-lite-debug.js"></script>    

Upvotes: 1

Related Questions