MithrilJS / docs

Source code for Mithril's documentation site
https://mithril.js.org
MIT License
1 stars 4 forks source link

Cannot use object itself as key #17

Closed ciscoheat closed 1 month ago

ciscoheat commented 4 years ago

Mithril version: 2.0.4

Browser and OS: Win 10, Chrome 81

Code

var data = [
  {name: "A"}, {name: "B"}, {name: "C"}, {name: "D"}
]

var Chars = {
  view: () => data.map(char => m('p', {  
    // Using key: char gives [TypeError: Cannot read property 'key' of null]
    // Changing it to char.name works.
    key: char, 
  }, char.name))
}

m.mount(document.body, Chars)

function randomInt(max) {
  return Math.floor(Math.random() * Math.floor(max))
}

setInterval(() => {
  const from = randomInt(4), to = randomInt(4)
  const el = data.splice(from, 1)[0]
  data.splice(to, 0, el)
  m.redraw()
}, 500)

Flems link

Expected Behavior

I expect no error.

Current Behavior

The example gives the error TypeError: Cannot read property 'key' of null when using an object as key. It works when changing it to a primitive type.

Context

When using nested json as data, a value key isn't always available, so being able to use the object itself as key is useful.

tjkandala commented 4 years ago

I'm new to Mithril, but I believe that this is happening because vnode keys are used as the property name for the internal 'KeyMap' object, so keys must be strings. This is also documented here.

This could be fixed by using ES2015 maps, but that would be counterproductive.

kczx3 commented 4 years ago

Map is supported in IE11 which I believe is Mithril’s minimum supported IE version. All other browsers would support Map as well.

dead-claudia commented 4 years ago

This is expected behavior, but undocumented. Mithril internally uses null-prototype objects as dictionaries, not the more-recent maps. If someone wants to file a pull request adding this edge case to the docs, I'd gladly review it.