We recently had the opportunity to build a relatively small prototype application with the front-end JavaScript framework Svelte. Along the way, we took note of some issues we came across as Svelte beginners to help other developers that might come across similar issues. In this article, we will talk about using svelte to add attributes to HTML elements conditionally.
Svelte allows users to set HTML element attributes using JS expressions dynamically.
<script>
const nextVideo = 'GVM_GBWIk4Y';
</script>
<a href={'http://www.youtube.com/watch?v=' + nextVideo}>Next Video</a>
The script above will generate an HTML element that looks like this:
<a href="http://www.youtube.com/watch?v=GVM_GBWIk4Y">Next Video</a>
These expressions and how to use them are very straight forward; however, we ran into a couple of situations where we wanted to add an attribute conditionally. Let’s use the following code as an example.
<script>
const battingOrder = [
'Tim Anderson',
'Yoan Moncada',
'Yasmani Grandal',
'Jose Abreu',
'Eloy Jimenez',
'Edwin Encarnacion',
'Luis Robert',
'Nomar Mazara',
'Nick Madrigal'
];
const generateStyle = (index) => (index % 2 == 0) ? 'background-color: #BEBEBE' : '';
</script>
<body>
{#each battingOrder as batter, index}
<div style={generateStyle(index)}>{batter}</div>
{/each}
</body>
In this example, we are using the svelte framework to build one new div for each batter in a baseball lineup. To help with readability (and to help illustrate this point) we are going to use the style attribute to set a background color on every other div. Our generateStyle function returns one of two values, ‘background-color: #BEBEBE’ if the index is even, otherwise we return an empty string. The code above will generate these HTML elements:
<body>
<div style="background-color: #BEBEBE">Tim Anderson</div>
<div style="">Yoan Moncada</div>
<div style="background-color: #BEBEBE">Yasmani Grandal</div>
<div style="">Jose Abreu</div>
<div style="background-color: #BEBEBE">Eloy Jimenez</div>
<div style="">Edwin Encarnacion</div>
<div style="background-color: #BEBEBE">Luis Robert</div>
<div style="">Nomar Mazara</div>
<div style="background-color: #BEBEBE">Nick Madrigal</div>
</body>
Notice how every element has a style attribute, even if the attribute does not contain a value. We wanted to know if there was a way we could write our code so Svelte did not add an attribute if there was no actual value for that attribute. Doing so would make the HTML easier to read and, in some cases, prevent us from generating invalid HTML. After some research, we found a couple of helpful resources that explained how to do this.
It turns out that setting an attribute to a nullish value (null or undefined) will prevent the attribute from appearing on an HTML element. In the sample case above, if we wanted to prevent the odd indexed elements from containing a style attribute at all, we could change from:
const generateStyle = (index) => (index % 2 == 0) ? 'background-color: #BEBEBE' : '';
To:
const generateStyle = (index) => (index % 2 == 0) ? 'background-color: #BEBEBE' : undefined;
Or:
const generateStyle = (index) => (index % 2 == 0) ? 'background-color: #BEBEBE' : null;
Which would generate the following code:
<body>
<div style="background-color: #BEBEBE">Tim Anderson</div>
<div>Yoan Moncada</div>
<div style="background-color: #BEBEBE">Yasmani Grandal</div>
<div>Jose Abreu</div>
<div style="background-color: #BEBEBE">Eloy Jimenez</div>
<div>Edwin Encarnacion</div>
<div style="background-color: #BEBEBE">Luis Robert</div>
<div>Nomar Mazara</div>
<div style="background-color: #BEBEBE">Nick Madrigal</div>
</body>
Our advice if you find yourself in a situation where you want to conditionally add attributes to an HTML element using svelte, is to use a nullish value (null, or undefined) in cases where you do not want the attribute to appear on the element.