When you should not use JavaScript fat arrow functions


Code readability is extremely important. By some estimates, we’ll spend significantly more of our time as developers reading and mentally parsing code rather than writing it. Arrow functions can both improve and hurt readability. It is very important that we make choices that optimize our code for readability. I’m going to assume for the sake of this article is that the readers are using some form of JavaScript modules with a single module per file. The goal of the module, when it comes to readability, is to make it easy for a person to understand what that particular module does, and the interface it provides for use in other modules.

In JavaScript, ES2015 (i.e. ES6) introduced the fat arrow function syntax, and it is great … for some use cases. But I keep seeing developers recommending and using arrow function assignment to a const variable as a substitute for using function declaration. I think that is a problem and contributes to poor readability in most JavaScript files that use that pattern.

Let’s back up a bit and define some of these terms, and then we can talk about arrow functions, where they are great and where traditional functions can be used to improve readability.

 

Function Declaration

Using the function keyword to declare a function. Functions declared in this manner get their own scope (and also close over the enclosing scope). They will be hoisted to the top of their containing scope. Unlike variables declared with var that get hoisted though, functions declared and hoisted in this manner are callable immediately, regardless of where they are declared in the code scope.

function myFunc() {}

 

Function Expression

Using an assignment to assign an anonymous or arrow function to a variable. We used const here to ensure the variable cannot be re-assigned. The two statements are different, mainly in how they treat the this keyword.

const myFunc1 = function() {}
// or
const myFunc2 = () => {}

 

Arrow Functions

Arrow functions can be awesome. And assigning it with the const keyword does provide a benefit that means the function cannot be redeclared or overwritten. One of the best uses for arrow functions is in simple callback methods, like map, sort, and reduce. My personal rule of thumb is to move to a declared function once an arrow function exceeds 2 lines, although individual circumstances can warrant exceptions.

const doubledArray = originalArray.map((arrItem) => arrItem * 2);

But, when arrow functions start to extend to multiple lines, they can start to create problems when it comes to the readability of the code in my opinion. An assignment via const must come before those variables can be used in a module. Some of you may see where we’re going here.

 

The Problem

The main core of JavaScript modules can often be pushed down out of sight by the const assignments that must be done prior to being able to be used.

const _utility1 = () => {
  // multiple lines of code here
};
const _utility2 = () => {
  // multiple lines of code here
};
const action1 = () => {
  // multiple lines of code here, which use _utility1() and _utility2()
};

export { action1 }

If the example above, the interface for this module is via the action1 function, which uses the 2 utility functions. Because they are being assigned to const variables, they need to be declared prior to exporting them for use outside the module. The important information for someone reading this module isn’t the implementation of the utility1 or utility2, and they likely don’t even need to know about the specific implementation of the action1 function. They need to know that they can use action1 outside of this module.

 

Using function declarations (and good names) to solve the problem

A fairly simple rewrite to take advantage of function hoisting, along with high quality names, can make the file much more scannable and ensuring that a developer reading the code gets the information they need without having to read any extraneous code first. They can always dive into the individual functions as needed, but when opening the file for the first time, it is very clear what is going on.

export { wellNamedFn }

function wellNamedFn() {
  // multiple lines of code here, which use _utility1() and _utility2()
}
function _utility1() {
  // multiple lines of code here
}
function _utility2() {
  // multiple lines of code here
}

By utilizing the function hoisting feature of JavaScript, the isolation that modules provide (meaning there is not a concern that the function would get redefined),  the code can be arranged so that the most important information is front and center when a developer opens the file to read the code.

I’ll leave off with a hello world example, a React Component that has a utility function (often many utility functions) before the render function.

class HelloWorld extends React.Component {
const getGreetingSubject = () => 'world';

render() {
return <h1>Hello {getGreetingSubject()}!</h1>
}
}

vs

class HelloWorld extends React.Component { 
render() {
return <h1>Hello {getGreetingSubject()}!</h1>
}
}

function getGreetingSubject() {
return 'world';
}

It may seem relatively contrived in these small examples, but in real world cases, the irrelevant code can be significant and cause readability issues. By considering what is most important in each module, high readability can be ensured by focusing on making those important pieces of code very clear.

EmberJS 2018: Dogfooding Ember on Emberjs.com


I started using Ember about 18 months ago. In that time I’ve come to learn the ins and outs, the good parts, and the frustrating parts, that make up Ember. I’ve wanted to give back to the framework that I was using, and I have made some minor fixes to some of the addons in the ecosystem, and just recently (yesterday) got a PR merged to fix an issue with the Ember Guides. But I get ahead of myself – I struggled to jump in and contribute to Ember itself. When there was a call for blog posts about the future of Ember in 2018, I knew what I wanted to speak about my experience and provide some motivation for the Ember community and team members to dogfood our own product to make marketing Ember better and to help make contributing simpler. From a technical point of view, I believe Ember is one of the top frameworks already, and it’s a shame more people don’t know that.

What is Dogfooding? – Its a term used to describe an organization using its own product.
The idea is that if the organization truly believes its own product to be superior, it would use the product itself.

Marketing Ember

I did a little competitive analysis when writing this post. Of all of the major frameworks I looked up, Ember was the only one that didn’t dogfood their framework for the main website. React, Angular, AngularJS, Vue…Knockout, Polymer, Meteor – I looked up quite a few of the common front end Javascript frameworks new and old, and every single one of the sites I looked at used their framework to build their site – except for Ember.

I know there are historical reasons for this. Well, I don’t think they hold water anymore. This year, 2018, Emberjs.com needs to be built with Ember. Other people have written in their posts about the need for better marketing of Ember. But all of that marketing falls flat if, when a prospective dev comes to the Ember website, and opens Wappalyzer, inspects the source code, or looks on Github and finds that it isn’t Ember. They don’t know any of the reasons for it. They just know that the people that build Ember don’t use it on their website. And that can put a seed of doubt in their mind. Maybe enough to move on to another framework.

New Contributors

The other aspect of this is the loss of potential contributors.

When I looked into what I could contribute to Ember, I gravitated toward helping the Learning Team with work on the emberjs.com website. So I went to the EmberJS repo on Github, found the Website Source, and started looking at the issues – found one or two I thought I could help with. I cloned the project, and tried to get it to run and was perplexed. My expectation was an Ember app, and instead I found a Ruby and Middleman website. When trying to get that running locally I found that there were known bugs running it on Windows, my main development environment at home. I did reach out on the Ember Slack and a few people tried to help me get things running to no avail. And I let it lay there for a bit, got busy at work and other side projects, and at that point, Ember had lost a potential contributor. I didn’t even know there were other apps that made up the website, so that was it at that time.

Ember is used by developers who tend to be focused on the front end ecosystem. And while there are plenty of front end devs who are great at Ruby and Middleman, that isn’t going to be the norm. And frameworks need new blood on the team. They need the enthusiasm people new to helping out of the framework can bring. The new ideas that come with those people. So let’s make it easier to do so, by ensuring Emberjs.com is built in the framework they likely use every day. Or at the simplest, in the languages they use every day (HTML/CSS/JS).

As a front end framework, obviously there needs to be some dev-ops and backend APIs for the website to work. But I’d argue that the Emberjs.com website is THE place for Ember to shine. If it can be done in Ember, it should be done in Ember. I envision the website repo on github as one of the places to go to see how to use Ember in practice.

Call to Arms

There are a number of benefits that come with dogfooding Ember:

  • Greater awareness of rough areas and earlier problem detection
  • More accurate marketing message around exactly what benefits Ember provides
  • Higher level of confidence from those evaluating Ember and for those using it
  • Boost to morale in the community to see Ember being used and promoted by the core team

There are already pieces of the site built with Ember. The Learning Team is actively working to transition more parts to Ember, just launching the recently Emberized Guides app a few days ago. This is not a critique of those efforts, but rather to encourage the effort of Emberizing the website to continue, and to set forth the goal of having the entire Ember website made from Ember this year, in 2018. And I encourage anyone reading who has interest in assisting in that effort to join me in asking what we can do to help.

Vanilla JavaScript vs. Framework Functions


Had a quick conversation at work today about whether or not it was good to use built-in framework functions for tasks that are simple to write in vanilla JavaScript. For example:

angular.isFunction(fn) 

vs

typeof fn === 'function'

I’ve tended to do the vanilla JavaScript, but while checking if something is a function is almost identical in complexity/length, while others can be (slightly) more complex:

angular.isObject(yourVariable) 

vs. 

yourVariable !== null && typeof yourVariable === 'object'

Still, either way is pretty readable, and fairly clear what it is doing. I wonder if this is what leads to people bashing frameworks like Angular for teaching people the “framework” rather than vanilla JavaScript, as newer coders who may not have ever had to check variable types who are learning Angular may use the framework checks without knowing how to do a similar thing in vanilla JavaScript.

I like to collect snippets that will help me, and reuse them where appropriate. This probably tends to skew me towards vanilla JavaScript, because I want my snippets to work no matter what project I am working on. For example, the following snippet gets the class (or type) of a JavaScript variable.

/**
 * getClass - get real type of JavaScript object 
 * @param object
 * @returns {string}
 */
function getClass(object) {
    return Object.prototype.toString.call(object).slice(8, -1).toLowerCase();
}

/*
getClass({}) // "object"
getClass([]) // "array"
getClass(function(){}) // "function"
getClass('') // "string"
getClass(1) // "number"
*/

I came away from the conversation thinking there was not one right way. If you are writing an app with the help of of a framework, there is nothing wrong with using the tools the framework provides. At the same time, it shouldn’t become a crutch where a framework is needed because a developer isn’t comfortable doing the same thing in vanilla JavaScript.

Getting the number of Facebook shares and/or likes of a URL


So…you want to display the number of times your url has been shared/liked on Facebook, but you don’t want to just use the Like Button with the count?  I don’t blame you, while I use the Like button when appropriate (and that IS the easiest way to get that number, it doesn’t help you at all when you want to do something a bit cool with the information, or display it in a unique format.

So, there are 2 ways currently to get an URL’s Facebook Shares.  You can make a query against the Facebook REST API and use the links.getStats method, or you can use the Graph API to make an FQL (Facebook Query Language) call.

The REST API is really easy to use, but unfortunately, it is deprecated, so Facebook could shut it off tomorrow if they wanted to.  Personally, I doubt it gets shut off, but don’t come crying back here if you use it and something stops working because they do.

To make a call using the REST API, using one of my more popular posts as an example, you can make a query to the following URL like so:

http://api.facebook.com/restserver.php?method=links.getStats&urls=http://www.local-pc-guy.com/web-dev/facebook-feed-dialog-vs-share-link-dialog

That will return a block of XML (yes, XML) that looks like this:

<links_getStats_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd" list="true">

    <link_stat>
        <url>
            http://www.local-pc-guy.com/web-dev/facebook-feed-dialog-vs-share-link-dialog
        </url>

        <normalized_url>
            http://www.local-pc-guy.com/web-dev/facebook-feed-dialog-vs-share-link-dialog
        </normalized_url>

        <share_count>22</share_count>
        <like_count>51</like_count>
        <comment_count>0</comment_count>
        <total_count>73</total_count>
        <click_count>0</click_count>
        <comments_fbid>468455836580018</comments_fbid>
        <commentsbox_count>0</commentsbox_count>

    </link_stat>

</links_getStats_response>

Then you’d just need to parse that returned XML into a usable format and grab the values that you want.  Generally you are going to want the total_count element, but sometimes you may want to differentiate between Shares and Likes.

Unfortunately, as mentioned, the REST API is deprecated, so if that concerns you, you can use FQL to query Facebook using the Graph API.

You can query the link_stat table with something like the following query:

SELECT 
    url, 
    normalized_url, 
    share_count, 
    like_count, 
    comment_count, 
    total_count, 
    commentsbox_count, 
    comments_fbid, 
    click_count 
FROM 
    link_stat 
WHERE 
    url="http://www.local-pc-guy.com/web-dev/facebook-feed-dialog-vs-share-link-dialog"

You can make a GET request to the Graph API and the Graph API will give you back a JSON response listing the fields you requested.

https://graph.facebook.com/fql?q=[QUERY]
https://graph.facebook.com/fql?q=SELECT url, normalized_url, share_count, like_count, comment_count, total_count, commentsbox_count, comments_fbid, click_count FROM link_stat WHERE url="http://www.local-pc-guy.com/web-dev/facebook-feed-dialog-vs-share-link-dialog"

The returned JSON should look like this, and is very easy to parse for the data you want.

{
   "data": [
      {
         "url": "http://www.local-pc-guy.com/web-dev/facebook-feed-dialog-vs-share-link-dialog",
         "normalized_url": "http://www.local-pc-guy.com/web-dev/facebook-feed-dialog-vs-share-link-dialog",
         "share_count": 22,
         "like_count": 51,
         "comment_count": 0,
         "total_count": 73,
         "commentsbox_count": 0,
         "comments_fbid": 468455836580018,
         "click_count": 0
      }
   ]
}

 

My recommendation is to go ahead and get comfortable with, and use, the FQL query syntax and the Graph API.  That way you are protected against the REST API going away and you get JSON, which is slightly easier to work with than XML.

Enjoy querying against Facebook, FQL is quite powerful and there is quite a bit of information you can get with a bit of digging through the docs.

Removing (Google) CDN version of jQuery from Html5 Boilerplate?


I recently added a pull request to Html5 Boilerplate to remove the use of the Google CDN for loading jQuery.  Little did I know that it would stir up some great debate about whether using a CDN, specifically the Google CDN, was the best practice or if concatenating and minifying your code into a single file is better.

The pull request was based on 2 things, 1 was a conversation Karen Ford (my co-worker) and I had with Alex Sexton at the jQueryTO conference in Toronto. The second was a very data-driven blog post Alex referenced by Steve Webster posted in late 2011 about Caching and the Google AJAX Libraries.  In that post, Steve points out that there is generally very little performance benefit from loading jQuery from the CDN due to the amount of fragmentation that exists in what versions of jQuery are being used in the wild.

Read more