WebReflection / hyperHTML

A Fast & Light Virtual DOM Alternative
ISC License
3.07k stars 112 forks source link

Question about Wire IDs example code in doc #259

Closed dephiros closed 6 years ago

dephiros commented 6 years ago

Thank you for your awesome work.

I am trying to learn hyperHTML through the doc and saw this example in "Wire IDS" sections:


const info = {some: 'data'};
const sameLI = hyperHTML.wire(info)`
                <li></li>`;

// what if we use same template later on?
console.assert(
  sameLI === hyperHTML.wire(info)`
                <li></li>`,
  'same reference means exactly the same node'
);

The assertion is false every time on latest Chrome Mac. I am confused because I thought they should be the same. Also, if the template string is different, I assume that the reference would be different?

albertosantini commented 6 years ago

I think that console.assert is not enough deep. :)

Using a quick&dirty deep comparison:

console.log(
  JSON.stringify(sameLI) === JSON.stringify(hyperHTML.wire(info)`<li></li>`)
); // true

And the reference is the reference passed to wire api.

same reference means exactly the same node means same reference [of the object info] means exactly the same node.

WebReflection commented 6 years ago

Those are two different template strings, a behaviour introduced, and described, here: https://itnext.io/a-tiny-disastrous-ecmascript-change-fadc05c83e69

If you use a single source to create the element the equality will be true.

This is also the most common , if not only, use case for templates, the rest is for tests or not real world applications.

This won't be fixed, it's expected

dephiros commented 6 years ago

@WebReflection, would you mind give an example of using a single source to create the element? Can you help explain also how that behavior affect this example? Does it mean that

wire(item)
    `<li>${item.text}</li>`

will not be the same each time?

const {bind:hyper, wire} = hyperHTML;

const todo = [
  {id: 0, text: 'write documentation'},
  {id: 1, text: 'publish online'}
];

// show the todo list
update();

// add an item in 2 seconds
setTimeout(() => {
  todo.push({
    id: 2, text: 'create Code Pen'
  });
  update();
}, 2000);

function update() {
  hyper(document.body)`
  <ul>
    ${todo.map(item => wire(item)
    `<li>${item.text}</li>`)}
  </ul>`;
}

And lastly, if the example in the doc is not correct, maybe we should update the doc. It would help clarify wire for me and others. I wouldn't mind help updating the doc once I understand the behavior 😃

WebReflection commented 6 years ago

I'm on vacation and the code you wrote works as expected.

Wiring, like binding, is always the same node if you use the same template literal, which you do already, so it's fine.

If you use two template literals, even if looking similar, nodes will be different.

But again, your example works just fine.

Everything else is explained in the post I've linked.