Blog History Page 4

Should We Avoid Ternary Operators?

Should We Avoid Ternary Operators?

![](https://i0.wp.com/www.aggrippino.com/wp-content/uploads/2021/08/ternary_operator_carbon.jpg?resize=1024%2C512&ssl=1)
I recently read a Facebook post which suggested it was better to use a ternary operator instead of an if…else statement whenever the result would be a single line of code. That doesn’t seem right.

I’ve noticed this trend toward shorter, smaller code, and I understand the appeal. If I can do in one line of code what used to take six lines, it feels more efficient. However, when it comes to executing the code, there’s no performance difference between an if…else statement and a ternary operator.

Code Quality Perspective

Measuring programming progress by lines of code is like measuring aircraft building progress by weight.
― Bill Gates

It doesn’t seem very long ago that Software Engineers conflated the number of lines written with the skill of the programmer or the quality of the code… More lines of code meant better code. In Bill Gates’ quote, he’s addressing this misconception, but the point is the difference in perspective from then to now.

Ternary Operator Benefits

Efficiency… but not really
The ternary operator feels like a hack that makes our code more efficient. However, efficiency is most important during execution. During development, the most important thing is readable code.

Smaller code
A web page does load faster if the browser has less to download, but this type of optimization is the job of a minification tool, not a programmer. And it is well known that “premature optimization is the root of all evil“.

Readability… but not usually
Sometimes compressing a complex concept into a single line makes code easier to understand. This is the only time the ternary operator should actually be used. It’s easy to abuse the ternary operator, though, resulting in unreadable code.

Ternary Operator Facts

In favor of ternary operators

  • Sometimes using the ternary operator makes code easier to understand by compressing a complex concept into a single statement.

In favor of if…else statements

  • Usually the if…else syntax is easier to understand. The separation between the condition and each action allows the reader to pause and consider each action and when it occurs.
  • The ternary operator further encourages terse code which is harder to read and can lead to mistakes like failing to consider falsy values.
  • A ternary operator may be easy to understand, and look nicer, when it’s first written. However, it’ll be more difficult to understand for another developer, or even the original developer when returning to the code months later.

Conclusion

Of course we shouldn’t stop using ternary operators! On either side of the debate, there’s an argument for improving readability of code. So, use it when it’ll improve readability. But there are more reasons to use if…else syntax. We should avoid ternary operators, but it’s a guideline, not a rule. And even when considering rules, we must remember that “A foolish consistency is the hobgoblin of little minds“.

How to really check with JavaScript if CSS failed to load from a CDN

How to really check with JavaScript if CSS failed to load from a CDN

![](https://i0.wp.com/www.aggrippino.com/wp-content/uploads/2019/12/error-loading-min-e1629184314699.jpg?resize=1024%2C512&ssl=1)
I want to load a third-party CSS stylesheet from a CDN, but I’m concerned how it will affect my site if the CDN goes down. *How do I use JavaScript to check if a CSS file has loaded* so I can load a local fallback instead?

This can’t be a new idea. I can get the answer from a web search, can’t I? …

Incorrect Solution #1

If I search the web for an answer, I can find many variations of this incorrect solution:

```
// Just an example:
cdnUrl = `https://cdnjs.vinceflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css`;
localUrl = `css/all.min.css`;

let loaded = false; for ( var i = 0; i < document.styleSheets.length, i++ ) { if ( document.styleSheets[i].href === cdnUrl ) { loaded = true; } } if ( !loaded ) { const localCss = document.createElement(link); localCss.rel = stylesheet; localCss.href = localUrl; document.querySelector(head).appendChild(localCss); }


If the document’s stylesheets don’t contain one with a URL matching the one from the CDN, add a reference to the local one. It doesn’t work, though. `document.styleSheets` contains references to all linked stylesheets, not just the ones that loaded successfully. Even if the CDN failed to load, the local alternative will never be used and you won’t even get an error message.

## Incorrect Solution #2

<div class="incorrect-solution-target"></div>```
<pre class="EnlighterJSRAW incorrect-solution" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="js" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">// Just an example:
cdnUrl = `https://cdnjs.vinceflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css`;
localUrl = `css/all.min.css`;

let loaded = false;
for ( var i = 0; i &lt; document.styleSheets.length, i++ ) {
  if ( document.styleSheets[i].href === cdnUrl ) {
    if (document.styleSheets[i].cssRules !== null) {
      loaded = true;
    }
  }
}
if ( !loaded ) {
  const localCss = document.createElement(`link`);
  localCss.rel = `stylesheet`;
  localCss.href = localUrl;
  document.querySelector(`head`).appendChild(localCss);
}

This one looks a little better… CSSStyleSheets have a cssRules property which shows the rules associated with the stylesheet. If it didn’t load, it’ll be null, right? Wrong. In Firefox, cssRules is an empty array when the stylesheet fails to load. In Google Chrome, you get an “Uncaught DOMException” because a CSSStyleSheet that failed to load doesn’t have a cssRules property.

A real solution?

<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="js" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">export function cssFallback(cdnUrl, localPath) {
  // Create a new link tag and append it to the document head
  const loadAlternate = () =&gt; {
    console.log(`Loading ${localPath}.`);
    const link = document.createElement(`link`);
    link.rel = `stylesheet`;
    link.href = localPath;
    document.querySelector(`head`).appendChild(link);
  }

  // Identify the CDN stylesheet
  const stylesheet = Array.from(document.styleSheets).filter((s) =&gt; s.href === cdnUrl)[0];

  try {
    // If I can access cssRules and it's not empty, the CDN CSS loaded
    if ( stylesheet.cssRules.length === 0 ) {
      console.log(`The cssRules for ${cdnUrl} is empty.`)
      loadAlternate();
    }
  } catch (e) {
    console.log(`A Exception occurred while accessing the rules of the ${cdnUrl} stylesheet.`);
    console.log(e);
    loadAlternate();
  }
}

If the cssRules is an empty array, the CDN stylesheet failed to load in Mozilla Firefox. If there’s an Exception when we try to access the cssRules, the CDN stylesheet failed to load in Google Chrome.

Eleventy's Cool URIs

While getting started with 11ty, I saw in the output folder that an index.md file would become index.html, as expected, but README.md became README/index.html. I didn't understand why there was a special case for the README file.

It took me a minute, but I found it with a reference to an article at the W3C stating (among other things) that cool URIs don't have file extensions.

Okay. I get it. I would've expected something like that to be my job, not the tool's, but it makes sense and I agree. But what do I do if I really want to have a named output file. There's gotta be a way. Well, scroll down. The permalink front matter value allows me to specify the relative URL of the file that will be generated.