Contents
Recap
More with Custom Elements
React, not overreact
Summary
1. Recap
So far, we’ve defined what web components a...
For further actions, you may consider blocking this person and/or reporting abuse
What is the point of attrs ??
over
When
this.constructor.observedAttributes
always gets you the attributes Array (if required at all)It just acts as a map, and it's not required at all.
I saw that pattern when looking through other web components in the wild, and thought it was a nice way to organize attributes in one place, and maybe even alias them like we've done there.
So the next question is: What is the point of aliasing?
Convenience, really. If you wanted to decouple the API from the implementation, this makes it a little more convenient to change things in the future. For example, if I wanted to rename the attribute, I can do it in the
attrs
object and not have to refactor the rest of the component where I've addressed it.Do you think there's a better way to do this? The simple alternative I can think of is use the attribute string directly, and then do a find-and-replace if things change.
Good point "future changes"
You will have a cleaner and smaller class when you declare all that sh* outside the class (at the top of your file)
Note #1 All good minifiers will replace references with the const value, so you get smaller code as well
Note #2
my-component
is often parameterized (is that a word?) asstatic tagName
on the class in recent examples as well.WHY?!? It is available on the component instance as
this.localName
orthis.nodeName
There's two things I want to add here:
Setting up the timer in the constructor and removing it in the
connectedCallback
would have meant the component would have stopped working if it was ever removed from the document and inserted elsewhere. Setting it in theconnectedCallback
to re-start it when re-attaching is the correct way about this.It is not entirely correct that the attribute for the delay value is only queryable when the element is mounted. If the element has already been parsed by the time the custom element is defined, the constructor will have full access to the element and its children, including attributes. Only if the custom element is already defined before the element is parsed, the constructor will run before any of the attributes or child elements have been parsed.
If you already have an
attrs
attribuet, then I would hope nobody would actually comma-separate them and instead just write something like this:Last but not least, the final version of the component would behave somewhat inconsistently. Detaching the component would initially pause the counting. Updating the interval attribute would then resume the counting. Connecting the element again would then start a second interval that could never be cancelled anymore and would continue to count up until the page is closed.
An easy way to fix this would be to just check if the object is actually connected in the
attributeChangedCallback
😁Thank you very much for your feedback.
This makes so much sense, and I don't know how I missed this!
This has taken me a quite a while to wrap my head around. I had someone else also flag this for me when I did the first post, and to be honest it hasn't clicked until now. I'll work on the correction and update the post. Thank you!
Good shout! I'll add that in too and signpost that by doing so all of your attributes will be tracked, which is probably what you'd want most of the time.
Great catch! I definitely didn't play that scenario out. I'll make the correction!
Honestly, thank you so much for taking the time to read the post and give me feedback! Greatly appreciate it.
Your article is a fantastic resource for anyone looking to delve deeper into this subject. I'll definitely be sharing it with my colleagues.
Thank you for your kind words!
This is definitely a great article! I was delighted with the first part, and then there’s the second! thank you
One pattern I end up repeating for pretty much every slightly larger component I write is this:
Then I can just add methods like
xIntervalChanged(from, to) { /* ... */ }
instead of having a long if in a single method.Same for Events: