Extending a Contextual Component’s Block Params in EmberJS

Did you know that if you yield a hash twice from a template, they get merged for the block params on the consuming end? Check it out:

This is a little trick I saw on a DockYard post: you can pass blocks of markup to specific parts of the component layout, removing the need for a new “block slots” API or addon.

Another use for this technique is to extend an addon’s contextual component API. Lets take ember-mapbox-gl, for example:

What’s happening above is that the map hash provided in the block params of {{mapbox-gl}} is merged with other contextual components that I’ve defined. This means that my {{projects-map}} component can still invoke and setup additional functionality as-needed.

This helps ensure that access to the map is still available from the “consumer” end. This avoids scenarios in which we thread down dozens of controller query parameters, for example, breaking encapsulation and creating confusion.

It also provides for a more consistent API when testing these internal extensions. For example, new coders could intuit from the template that the {{filter-distance-from-point}} component is probably a lot like the rest of the {{mapbox-gl}} proper API in that they receive a map instance reference and do something with it.

Alternatively, it’s possible to just natively extend the MapboxGLComponent class, copy the addon’s template (with the configured yield), and add your own keys, but extending addons in this way always felt a little idiosyncratic among the other approaches to composing behavior. Additionally, for testing purposes, I’ve found it harder to stub out the behavior of an extended component when wrapping it in a “provider” component would’ve helped better isolate behaviors. I’d rather my project’s components always be basic components without them sometimes being mappy components.

Thoughts? Let us know on Twitter.