Batman.js is no longer in production at Shopify and is not actively maintained.

This website is left for reference (and for old times' sake).


Batman.UniqueSetIndex extends SetIndex but adds a new consideration: its index contains first matching item for each value of the key (rather than all matching items).

test 'UniqueSetIndex takes the first matching item', ->
  batarang = new Batman.Object(name: "Batarang", type: "ranged")
  fists = new Batman.Object(name: "Fists", type: "melee")

  weapons = new Batman.Set(batarang,  fists)

  # Three ways to make a UniqueSetIndex:
  weaponsByUniqueType1 = weapons.indexedByUnique('type')
  weaponsByUniqueType2 = weapons.get('indexedByUnique.type')
  weaponsByUniqueType3 = new Batman.UniqueSetIndex(weapons, 'type')

  # additions to the base Set are tracked by the SetIndex
  grappleGun = new Batman.Object(name: "Grapple Gun", type: "ranged")

  for uniqueSetIndex in [weaponsByUniqueType1, weaponsByUniqueType2, weaponsByUniqueType3]
    equal uniqueSetIndex.get('ranged').get('name'), "Batarang"
    equal uniqueSetIndex.get('melee').get('name'), "Fists"

Using a Batman.UniqueSetIndex

Batman.UniqueSetIndex is batman.js's way of finding unique items in a Batman.Set. A UniqueSetIndex is like a hash: when you get a value from it,it returns the first matching member.

Since a UniqueSetIndex is a proxy of a Set, the easiest way to make one is to use Set::indexedByUnique:

weaponsByName = weapons.indexedByUnique('name')

weaponsByName is a UniqueSetIndex. To find a member by name, use get:

batarang = weaponsByName.get('Batarang')

batarang is the first item where name = "Batarang".

You can also make UniqueSetIndexes in view bindings:

<div data-context-batarang=''>
  <!-- `batarang` tracks `weapons` and will render the first item with name="Batarang"-->

SetIndexes are observable proxies of their underlying Sets. So, when the Set is changed (ie, items are added, removed, or modified):

  • The SetIndex is automatically updated by batman.js
  • Any view bindings or accessors depending on the SetIndex are updated

If an item is not found, the UniqueSetIndex is still tracked as a source. Later, if a matching item is added, bindings and accessors will be updated with the new value.

Help us improve our documentation!

Contributions to this page are welcome on Github. If you find a problem but you cannot fix it, please open an issue.

Discussion regarding batman.js documentation is also welcome on our mailing list.