This content originally appeared on Level Up Coding - Medium and was authored by David Bethune

Part 2: Working with Arrays
In Part 1 of this series, we examined the concepts of data binding in Typescript web components and looked at a two sample components that pass data using attributes and properties. In this section, we’ll see some Typescript methods for working with arrays, which is how we deal with lists of data. Along the way, we’ll start separating our code into modules and look further into passing data between them. We’ll also take a first look at using arrow functions to process items in a TS array.
Quick Index
Part 1: Properties, Values, & Data Binding
Part 2: Working with Arrays
Part 3: Working with JSON Objects
Arrays vs. Objects
Every programming language needs some way to deal with lists of data items, as opposed to just the individual items themselves. We could view the Pages JSON object in our example <dta-pages> component as a list — of pages.

There is another kind, the array. Arrays are different from objects in two ways. First, the items in an array don’t have a key. Instead, they go in a specific order. Their place in line is called the index. In JS and TS, an array is surrounded by square brackets as opposed to the curly braces around objects.


Iron Chef: Data Storage Showdown!
Each type of data storage has one clear upside, and one clear downside:
- Object values can only be accessed by their keys. There is no index.
- Array values have no keys. They can only be accessed by their index.
This makes objects great for getting something out when you know its name or label — like finding the balance of a single account using an account number as a key. But arrays are better when we need to walk through a list of items, such as generating a mailing list for all the accounts in a certain region. A list like that could be represented as an array of account numbers.
Since object values aren’t in any order, we can’t say, “Give me the Nth one.” And since arrays don’t have keys, we can’t say, “Give me the one called so-and-so.
It’s good programming practice to make our arrays contain only one kind of item, often a key into another object — or an index into another array. It may seem like it would be easier to just keep a list of all the customers with their balances, but in practice it’s easier to work with the smallest amount of data possible, and this is generally good programming advice. In other words, rather than passing around the entire list of customers, we can make arrays (and even other objects) that only contain the parts we need.
It’s a Dessert Topping and a Floor Wax
Often, we need both kinds of access to the same data. If we were to create any kind of menu for our pages, we would need to display a list of something — a list of page names? A list of page keys? (That would be ugly.)
We could expand our definition of each page to include a name to display on the screen, and we probably should. But we need a list of the page keys anyway. Then we can “walk through” that list when creating our menu output — whether that’s a list of buttons, a list of items on a dropdown menu, or however we want to write it.

The Maya Started at Zero, Too
If you haven’t encountered it before, arrays in JS have a strange property. Their index starts with zero. This means that the first item in the array has an index of zero. Not all languages work this way. The lovely Lua, which I adore, has 1-based array indexing. (In other words, the normal human kind).
Like driving on the left or right, whichever way you are used to will make the other seem confusing. Just don’t forget — ever — that JS has zero-based array indices.
Let’s test this out by displaying the second item from our pageArray in dta-page.ts:

If I add a temporary <div> and bind its contents to the value of PageArray[1], I should get the second item in my array.

DIY: Create a Color Palette in Code
When designing a real app, I like to start with a color palette. Let’s create a <dta-palette> component that can display a range of individual <dta-chip> color chips, one for each color in my palette. The data itself will need to be a list of individual color objects. Let’s go!
I’ll begin with a new file, dta-palette.ts. It should start with the Usual Suspects in Lit web components: the imports, the component definition, the CSS, and the render. I like to take “one I baked earlier” and just delete the parts I don’t need, and you can do that with any of the components we’ve played with so far.
If you were with me when we created the <dta-page> component, you saw how I like to design the use case first, then code for that. Let’s use that technique here. Inside my <dta-palette>, I know I’m going to need to output a number of chips, one for each color. Let’s hard-code a single chip and make sure it works, then evolve it to use a list.

Here, I’ve added a <dta-chip> element with one attribute, a color= value. If we pass the key of color (like violet here), we can “retrieve” that value as a property in dta-chip.ts.
Create a Color Chip
Now, I need to code the dta-chip.ts component to put something on the screen. I’ll start with another copy of that same, mostly empty file:

I’ve added CSS in the shadow DOM to define a new class for my chip, giving it a fixed color to start with. It’s important to note that CSS properties in Lit are truly static and cannot be set by outside values. This is important and we’ll see how it comes into play in a moment.
Adding the Component to the Page
One of the best things about web components is that they really are modular. To get our new palette onto the page, we could put it anywhere — on index.html, on the page viewer, or even one one particular page of output.
For now, let’s add <dta-palette> to the <dta-home> so that it shows up underneath whatever page we are visiting.

If you’ve been using my module loader technique, add the new components to the list of exports in the component loader.

Checking the Initial Output

With web components, I’m a big fan of iterative design. Some programmers would advocate building a lot of this palette top-down, working out the arrays and such before getting anything on screen. If you’re familiar with the terrain, that can work out very well — but if you’re taking first steps here or unsure of how your parts will come together, the best approach is to write the dumb-dumb version first. Make something simple without the functionality, then add that in pieces. As we’ll do now.
Notice that the chip is blue here and not violet. At this point, we haven’t “done anything” with the color= attribute that we passed in. To do that, we’ll define “violet” and our other colors. Feel free to use names and colors you like, and make as few or as many as you want to.
Defining Colors with a Module
Let’s double-down on my suggestion of making things modular by putting our color code somewhere else. After all, we might need these colors again in other components. The good news is that this module won’t need Lit. It’s pure Typescript.
I’ll add a colors.ts file in my modules folder:

Notice the use of const to define the value. We don’t want these colors changing. Also notice the important export keyword before the constant definition. This export, combined with our module loader, makes this object available in our model everywhere.
You can take hex colors from another application, like PhotoShop, in which case they must start with a # pound sign. You can also use HTML color names, like blue, orange, and red. If you’re not good at picking attractive color combinations, you can have a palette generator make some for you.

Loading Your New Module
To get this module into the app, we can use our module loader technique. I like to keep my module-loader.ts separate from my component loader, but the idea is the same.


Accessing Goodies in Your New Module
The code we wrote in colors.ts isn’t a web component itself, so we need to import it separately into the components that use it. Thanks to our module loader, there’s only one line to add to dta-chip.ts.

You might remember that I mentioned namespaces as a way to keep your modules separate from other people’s. In this case, that’s going to pay off because we can use the syntax import * as myNamespace where myNamespace is your namespace. In this case, that’s dta.
The result of this is that all of the objects we exported from those other modules will be available under the dta object inside this component! In other words, we’ve added everything from those modules into our model.
Each object we exported (in the modules we exported) is now available in this module — from the dta object. The key is the name we put on the export. Since colors.ts exports an object called colors, we can now access it with dta.colors. If we want the orange key from that object, we write dta.colors.orange.
Using a Color from The Palette
If the colors object is in our model (as a result of the import), we should be able to use it as the background color of our chip.
Inside the <dta-chip>, I’ve added a style= attribute with a background-color property set to a hard-coded value of ${dta.colors.red}.

You may be asking, “Why we didn’t just add it to the CSS style definition for the chip class?” The reason is that we can’t. We can’t use ${expression}to get data out of our model in that static definition of the shadow DOM’s CSS. So we will add it to the individual <div>. In VSCode, the IDE will prompt you if you type a key (or part of a key, as with orangeRed here).
Win, Go!
If we visit the site in the browser, the chip is filled with the color value from dta.colors.red.

While there is an HTML color named red, that’s not the color we’re seeing. It’s our custom dta.colors.red. Accessing that key returns its value, the hex code we need. This same object and its keys are now available anywhere we want them — throughout our entire application.
If I need a specific button later to be that same red (like a Cancel button), I can just assign the color directly with ${dta.colors.red}. This same color will work for anything else, too, like a text color or border. And while the ${expression} syntax makes that value available in every web component, we can also get to it directly (in a Typescript module) by just writing dta.colors.red without the ${}.
Congratulations! Your colors are fully modular and truly universal. You have just saved yourself a ton of work using (and updating) colors in your own web apps.
No Key, No Go!
If we do not exactly match a key in the dta.colors object, we’ll get null — a computer science way of saying “nothing.” We can verify this by trying a key that’s not defined. I’ll also set the default CSS color to gray so that we can tell we’re looking at a default.


Mr. Liszt, We’re Ready for You…
If this seems like an enormous deviation into objects and modules just to learn about arrays, you’re right! I put you through it because I don’t want to get to far into functions (my favorite topic and the most important one in all of programming) until we have some good gardening practices set up. Also, everything in JS is an object, as we said, so there’s no avoiding some discussion of that. Whew! And thank you.

Now that we have a chip working with a single color, we can extend the idea to an array of colors and one chip for each. We mentioned earlier the idea of using an array of keys as a sort of halfway house for objects. It gives us that ability to iterate or walk through the list — the list of keys!
Fortunately, JS has a built-in way to create that. It’s called Object.keys(). When we call Object.keys() with the object in parentheses, we get back an array of all the keys in that object. With that in hand, we could output a chip for each color/key.
Finding Your Place
But where should the list go? In the MVC model we’ve setup, it’s the <dta-palette> that needs to know about the list. The <dta-chip> only needs to know which one single color it should get. Let’s use Object.keys() in dta-palette.ts to get a list of the keys in the dta.colors object.

At the top of dta-palette.ts, I’ve added a new constant definition and set it to Object.keys(dta.colors). That gives me a list of the keys in the object, as an array. Now, I need to walk through it.
Say “Hello World” to Functions
To accomplish our walk through the array, we need to define a function. In essence, a function is just a recipe (the comp sci term is algorithm) for taking some input, applying some process, and returning some output. We won’t dig into the specifics of functions just yet, other than to look at them as recipes.
The best way to write a function is to say aloud, as if speaking to Igor from Frankenstein, the simplest possible way to describe what you want. For us, that would look something like this:
- For each color on the list…
- Draw a chip in that color.
This is, in fact, a program. The language is what we call pseudocode. Basically, you make it up in a language that makes sense to you. It’s often good to write this directly into your program, as a comment! Let’s do it.

The function we are writing needs to be insiderender() but before the return or output stage. Return is a keyword signaling that the function has finished its computation and can now “give back” (hence, return) a result.
Introducing .map()
You’ll be pleased to meet the TS .map() function. For it provides a very useful service… mapping over an array, which is the fancy comp sci way of saying “Hey, Igor, take everything on a list and do this to each thing.”
If you’re new to programming or TS, this is a lot to take in at once — and we’ll definitely look more closely at functions in a future episode, but let’s break down the key parts:

Inside an Arrow Function
Map takes each item in the array, does something to it, and then returns an array with the results of your recipe applied to that individual item. The does something part is called the arrow function because it is written after the TS => arrow symbol (typed as = equal sign followed by > greater than).
- First, we define the constant chips and set its value. That value is the array returned from palette.map(), in yellow.
- To make the function work, we need a parameter for the input. I called it color, in blue. That will hold our key as we iterate through each item in the array.
- Finally, we need the recipe itself, in pink. And this recipe takes advantage of a miraculous property of Lit!
Arrays Have a Magic Property in Lit
The code above that returns all our chip HTML <div> elements is much smaller and easier to understand than previous ways of doing this. Map() is one reason. The other is a special rule of Lit that goes something like this:
- An array of HTML is as good as HTML itself.
- Each item will be output in order.
This seemingly simple principle leads to much simpler code. Let’s examine it. We said that the arrow function in pink up above is what creates the result. In map(), that is the result of applying the function once to each item.
Lit will allow us to return HTML here, so we can build-up an array of actual HTML, then spit it all out.

With this arrangement, each key on the palette list results in one <dta-chip> item in the chips array. Each <dta-chip> has a color= attribute, and that’s the key of the color we want.
Map() Returns a New, Transformed Array
There’s a one-to-one correspondence between keys on the color list and <dta-chips> on the chips list. This is because map() returns an array with the same number of items as the array it’s given. This way, we’ll have one <dta-chip> for each color key in the array — the array that contains all the keys from the colors object. Perfect!

Because Lit outputs all of the HTML in the array in order, on line 36 we can just dump out the chips array that resulted from the map().
Taste The Rainbow
So our palette component should now be fully setup to generate one <dta-chip> for each color. We still need to add some code in dta-chip.ts to see the effect of the attribute we’re passing through.

As I mentioned before, attributes and properties are twin brothers. I’ll add a color property to the chip component to match my color= attribute.
Finally, in the <div> being returned, I’ll change the hard-coded background-color to access the dta.colors object and — off of that object — take the value of the this.color key. In other words, if we pass in color=red we should get the color number for red (the value under the red key). If we pass color=violet, we should get that hex number, which is what background-color is expecting.
I’ll add a tiny bit of CSS spice to render the palette as a grid, then we should be able to see it in the browser.


That’s a Wrap!
So, what have we done here? We looked at arrays vs. objects and when you might need both. We created two new web components with Lit to display a custom palette made of color chips. We used good design practice to create a separate module for our color code, exporting it as a JSON object and importing it when needed. Finally, we took advantage of the mapping feature of arrays in TS and the HTML feature of arrays in Lit to output one chip web component for each color in our universal colors object.
Up Next: Working with Objects
In our next segment, we’ll take a deep dive into Typescript technique for working with JSON objects. We’ll extend this color palette by adding more information to the model and use the special features of these objects to slice-and-dice that information in interesting ways. In addition, we’ll examine functions, which are simply objects that “do stuff.”
Until then… thanks for reading! See you soon.
— D
Level Up Coding
Thanks for being a part of our community! More content in the Level Up Coding publication.
Follow: Twitter, LinkedIn, Newsletter
Level Up is transforming tech recruiting 👉 Join our talent collective
Learning Typescript with Web Components: Part 2 was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.
This content originally appeared on Level Up Coding - Medium and was authored by David Bethune

David Bethune | Sciencx (2022-07-18T00:31:34+00:00) Learning Typescript with Web Components: Part 2. Retrieved from https://www.scien.cx/2022/07/18/learning-typescript-with-web-components-part-2/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.