question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Allow explicit instantiation of cells

See original GitHub issue

According to the official documentation, the canonical way to instantiate a cell is like this:

var x = {
  $cell: true,
  $type: 'div',  // or some other element type
  // ...
};

This automatically appends the cell to the end of the body tag (unless $type is 'body', in which case it gets injected instead). But this is very limiting: the claim that you can reuse cells by simply pasting them into existing apps is weakened by the fact that you have no real control over where those cells end up in your document without using an iframe.

Of course, as you are probably about to point out, there is already an undocumented solution to this problem:

var x = {
  $type: 'div',
  // ...
};

window.addEventListener('load', function() {
  document.querySelector('#myContainerElement').$build(x);
});

This works well, although it’s a little unfortunate that we have to wait for the load event because the $build function hasn’t been added to the existing DOM elements yet. This feature is powerful and useful, and I think it should be (at the very least) officially documented and supported.

It would be even nicer if we didn’t have to wait for the load event. Since we’ve already loaded the script by the time we get here, perhaps it would be better to put the $build function on some existing object so we can access it immediately:

document.$build(document.querySelector('#myContainerElement'), x);

It might also be nice to add a $parent key on the genotype that could be used to specify a (static) parent for the element:

<body>
<div id="myContainerElement"></div>
<script src="https://www.celljs.org/cell.js"></script>
<script>
var x = {
  $cell: true,
  $type: 'div',
  $parent: document.querySelector('#myContainerElement'),
  // ...
};
</script>
</body>

However, I hope you keep the imperative version as well, because it allows developers to avoid polluting the global namespace. For example:

// This does not work:
const x = {
  $cell: true,
  $type: 'div',
  // ...
};

// But this does:
const y = {
  $type: 'div',
  // ...
};

window.addEventListener('load', () => {
  document.querySelector('#myContainerElement').$build(y);
});

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:1
  • Comments:9 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
Caffeinixcommented, Jun 16, 2017

My concern is mainly about namespace collisions. For example:

var Element = { // Oops! I just overwrote the constructor for the built-in Element type!
  $cell: true,
  $type: 'h1'
}

Bugs like that are subtle, and will tend to come back to bite you long after you’ve forgotten what you named that variable.

As you say, there should only ever be one global variable in the app, representing the root element, so maybe this isn’t the most horrible thing. But it does feel like a spooky side effect in an otherwise very functional approach. (I also wonder about performance – do you go through every single property of window looking for a $cell attribute?)

I think a Cell() function or similar would be a safer and more explicit way of achieving the same effect, and if you decide not to implement it I’ll probably use the $build API out of an abundance of paranoia, but I wouldn’t call it an existential design issue. 😃

1reaction
gliechtensteincommented, Jun 16, 2017

@Caffeinix you are totally right that let and const variables don’t get detected in the global scope.

My first instinct to your comment was to ask “when would we need lexical scoping to declare cell variables though?”. It’s probably because in most cases I would only use a single Cell variable in the global scope to build an entire DOM tree, in which case there’s no need for lexical scoping to begin with.

But I do want to understand if there are cases where using let or const makes sense. Could you share some scenarios where using let or const instead of var makes more sense? Would appreciate your input. Thank you!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Explicit instantiation (C++ only) - IBM
An explicit instantiation of a template specialization is in the same namespace where you defined the template. Access checking rules do not apply...
Read more >
Explicitly use defaults for some parameters in class template ...
Instatiating the template with just default parameters is easy: options<> my_default_options;. But what if I want to change a subset of parameters? options<int, ......
Read more >
Explicit instantiation | Microsoft Learn
You can explicitly instantiate function templates by using a specific type argument to redeclare them, as shown in the example in Function ...
Read more >
bollu/timi - Template Instantiation Machine Interpreter - GitHub
A visual interpreter of the template instantiation machine to understand evaluation of lazy functional languages - GitHub - bollu/timi: A ...
Read more >
3.2.6.4.2. Component Instantiation—Explicit Binding ... - Intel
3.2.6.4.2. Component Instantiation—Explicit Binding Instantiation ... You can bind a component to an entity in several mechanisms. In an explicit binding ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found