DEV Community

Discussion on: Lets Build Web Components! Part 8: Mythbusters Edition

Collapse
 
bennypowers profile image
Benny Powers 🇮🇱🇨🇦 • Edited
import { html, render } from 'lit-html';

const hobbitTpl = ({name, ability}) => html`
  <dt>${name}</dt>
  <dd>${ability}</dd>`

customElements.define('muh-hobbits', class extends HTMLElement {
  set band(val) {
    this.__band = val;
    if (!Array.isArray(val)) return;
    // Would be a great place to use template Instantiation when it lands
    render(html`<dl>${val.map(hobbitTpl)}</dl>`, this.shadowRoot)
  }

  get band() { return this.__band; }

  constructor() {
    super();
    this.attachShadow({mode:"open"})
  }
});

const main = document.querySelector('main')
render(html`<muh-hobbits .band=${[
  {name: 'Frodo', ability: 'courage' },
  {name: 'Samwise', ability: 'loyalty'},
  {name: 'Pippin', ability: 'strength'}
]}></muh-hobbits>`, main)


But at this point you might as well extend from lit element. It's vanilla enough.

Collapse
 
dehuszar profile image
Samwise Gamgee

That's sorta what I was trying to get at though. Lit is a light framework, but it would be nice to see an example of how one passes in rich data to a string literal web component template using nothing but the core spec. I think part of the reason this myth persists is because there's not a clear explanation about how to do it without resorting to tooling.

I have tried a bunch of different ways, but can't get past the fact that attributes have to be strings, and there aren't clearly explained ways to otherwise pass complex data into the component.

The closest I've gotten is to just use the slot system and require each page-level template to visibly nest component, so that arrays, as in your example, can be mapped in such a way that values land in their intended sub-component attributes as strings.

Thread Thread
 
bennypowers profile image
Benny Powers 🇮🇱🇨🇦

🤷‍♂️

Web component specs are not meant to solve every high-level concern for every use case. They're low-level primitives.

Libraries (in contradistinction to frameworks) like lit-html etc are there to build on the specs to provide high level uses.

Future primitives like Template Instantiation will let libraries like those be even smaller and more efficient.

Thread Thread
 
westbrook profile image
Westbrook Johnson

This is a great point Samwise, there is a lot of ambiguity around this. I'm gonna show you one way that you can address this, but I'd be very interested in knowing whether you have a non-web component example of how this might be possible. Knowing what the explicit goals you might have is half the battle when it comes to architecting a useful solution. What I share below will be useful for some requirement, but likely not all, in this area.

In so far as you want a library free (except the polyfills) approach to passing rich data into a web component, I offer the following:

There are certainly things that could be said against this approach. In particular, the idea that JSON.parse() prevents the maintenance of identity is a big one. In response to that, I'd question how someone would actually rely on the idea of setting data as attributes beyond the initial load of a page. In that case, setting an initial identity that then can be maintained inside of the application by passing properties (theoretically you'd be in/have access to the JS scope at that point, so it would look like otherElement.customProperty = y) would absolve that issue.

What other use cases for communicating rich data between web components have you run into? I look forward to hearing about it! I think this is a really interesting part of the web components conversation, and techniques established and discovered in this area will benefit well beyond simply trying to set rich data on an element.