JavaScript Best Practices for Writing More Robust Code

John Au-Yeung - Jan 27 '21 - - Dev Community

Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62

Subscribe to my email list now at http://jauyeung.net/subscribe/

JavaScript is an easy programming language to learn. It’s easy to write programs that run and do something. However, it’s hard to account for all the use cases and write robust JavaScript code.

In this article, we’ll look at how to check for device types and status to make sure that our apps degrade gracefully.


Device Type Check

We should check the type of the device to see what features should be enabled. This is important since web apps don’t only work on desktops and laptops anymore.

Now we have to worry about mobile devices with various operating systems.

We can check the device type from the browser’s user agent. The global navigator object has the userAgent property that has the user agent, which has the operating system information as part of the user agent string.

For instance, we can use it as follows:

const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
Enter fullscreen mode Exit fullscreen mode

In the code above, we check for all the possible substrings in the user agent string for mobile operating systems. We mostly care about Android, iPad, and iPhone, but testing the other ones isn’t that hard.

It’s easy to spoof the user agent string to make our browser pretend to be something else. However, most people don’t do it and there aren’t many reasons for other people to do it, so it’s still a good way to check if a device is a mobile device and act accordingly.


Checking for Network Connection Status

Like checking for user agents, checking for the network connection status is important since lots of devices can go offline at any time.

Mobile devices move between fast and slow networks or to a place without cell phone signal reception. As such, we have to check for that so our apps fail gracefully when a device is offline.

Most browsers now support the Network Information API, so we can use it to check for network status easily.

We can check for the network connection type as follows:

In the code above, we just retrieve the connection type with the connection, mozConnection, or webkitConnection properties to get the initial connection object.

Then we use the effectType property from the connection object to get the effective network type.

Next, we add a change event listener to the connection object to watch for connection type changes.

As we can see, we don’t have to do much to watch for internet connection type changes. Therefore, we should definitely do this.

If we change the network connection type from the Network tab in Chrome to simulate network connection type changes or change network connection types in real life, we should then see console log outputs like this:

4g to 2g  
2g to 4g  
4g to 4g
Enter fullscreen mode Exit fullscreen mode

Checking for Feature Availability

Different features may be available for different browsers by default. We should check if the features we want are supported in the browser before we implement any feature.

We can check if a feature is supported by a browser with Can I Use before using a library that might not be supported.

There’s also the Modernizr library to detect features that are available within the given browser.

We can install Modernizr by adding a script tag:

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.min.js"></script>
Enter fullscreen mode Exit fullscreen mode

It comes with classes that we can use to toggle HTML elements on and off depending on whether something is available.

For instance, it comes with the cssgradients and no-cssgradients classes to let us add different styles for situations where CSS gradients are available and not available, respectively.

With Modernizr installed, we can do the following in our CSS code:

In the code above, we have a fallback image for situations where the CSS gradients feature isn’t available, as was the case inside the .no-cssgradients header selector.

And we have our normal CSS gradients in the .cssgradients header selector.

Then we can add our own tests for features like checking if jQuery is available after adding the script tag above:

window.Modernizr.addTest("hasJquery", "jQuery" in window);
Enter fullscreen mode Exit fullscreen mode

Conclusion

We should check for the device type by using the user agent. Even though it’s easily spoofable, most people won’t do it because it doesn’t provide much benefit.

Also, we should check for the connection status of a device by using the Network Information API that’s supported by many modern browsers.

Finally, we should check if a specific library or feature is available with Modernizr and Can I Use before using it.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .