What I Learned Today - 100 Days

SVG of W.I.L.T acronym

I loved writing 100 words for 100 days & now want to write 100 days of little HTML, CSS or JS (ES6) lessons. I'm going to write about methods and techniques that I use often, either at work or on personal projects. The lessons will be written from a NEWBIE (i.e. my) perspective, and so may not be perfect, but they will offer a valuable insight into the thoughts of a new developer. My goal is to learn/document things for myself, and to show people, particularly other new developers, how someone like me approaches my work and hopefully give them something they can relate to :) Thanks to Charlotte for the suggestion!

Day 1 - BEM # Back to top toggle

I keep getting tripped up at work by forgetting to write modular CSS classes. There are so many benefits to a robust CSS architecture that I really want to get it right. BEM is a methodology to achieve this. Block, Element and Modifier. A Block is a component or feature than can stand alone and is not dependent on any other code. It can be re-used anywhere. Next, an Element. This is always part of a Block and has no meaning on its own. Lastly, there is the Modifier. This changes the behaviour and/or appearance of a Block or Element.

Example:

.button is a block.

.button__label is an element.

.button--confirm is a modifier.

See resources here and here.

Day 2 - Arrow Functions # Back to top toggle

Also known as a fat arrow, =>. This ES6 feature is a fat topic, so I'll concentrate on one aspect today.

var elements = [
'Hydrogen',
'Helium',
'Lithium',
'Beryllium'
];
(elements.map(function(element) {return element.length}))
(elements.map(element => {return element.length}))
(elements.map(element => element.length))
(elements.map(({length}) => length))

Above is an altered version of the MDN JavaScript Demo, where you will find a wealth of information on what fat arrows can do for you. The first function in the list is written without fat arrows. The last three functions are variations of the first function, showing how fat arrows can be used to write shorter function expressions, and therefore less code. You will need a code compiler like Babel to compile fat arrows into ES5 syntax so older browsers can use your JavaScript.

There are a _lot_ of resources that try explaining this syntax. Try Wes Bos's introduction for a start. This is complicated subject matter, though, so I suggest searching around for different posts, reading a few and finding ones that make most sense to you.

Day 3 - Psuedo Selectors # Back to top toggle

I only just found out that ::before (:before) and ::after (:after) are psuedo elements, which are different from psuedo classes. Both of these are grouped under psuedo selectors. I like this quote from MDN ~

Even the most skilled web developers are still amazed by what's possible using selectors.

Psuedo selectors are only two types of selectors. The others are: simple selectors, attribute selectors, multiple selectors and combinators. All of these help us to target and style HTML elements.

So, psuedo selectors include both psuedo elements and psuedo classes. They are added to the end of other selectors, and don't apply to whole elements, only parts of them.

The psuedo classes (e.g. :hover, :focus, and :nth-of-type() - plus 38 others) style elements in a certain state.

The psuedo elements (e.g. ::after, ::before, and ::first-letter - plus 3 others, not including experimental ones) apparently need :: rather than :, although I've used them with only one. These don't depend on the state of an element.

See this MDN page for great examples and to use their awesome active learning playground (I did and it was great for learning)!

Day 4 - this # Back to top toggle

The this keyword is found in various programming languages, and behaves a certain way in JavaScript. Apparently even experienced developers get confused by it.

The button below logs to the console.

See this codepen for the code. It showcases one of the six ways this is used in JavaScript - thanks to what I learned from Zell Liew's great blog post. I really recommend this post for beginners - you can try the examples in your console! In short, this can be used globally, in object constructions, object methods, simple functions, arrow functions, and event listeners. See the MDN docs for more code-heavy examples.

Day 5 - Flux # Back to top toggle

Recently, I began to write React at work and I've been doing okay with presentational components, but much less so with business logic (I hear ya Brad Frost). I've heard that improving my ES6 will really help, so you'll see more little lessons on it, but I also want to touch on how to manage dynamic state. Despite the popularity of Redux, one of my developer friends recommended covering Flux.

Flux is an application architecture for React (that can also be used elsewhere) utilizing a unidirectional data flow. In essence, it is an observer pattern that offers one-way data binding. Very useful when you need to keep lots of components in sync.

action -> dispatcher -> store -> view

  • The action creator formats messages (what the user does) from the UI
  • The dispatcher takes the formatted messages and synchronously sends them to different stores
  • The store holds all state logic and changes it by deciding what actions it wants to pay attention to
  • The view takes changes from the store and updates the UI

Please look at Lin Clark's great cartoon guide for more details. For a more code-heavy example, see here. I feel like the best way to learn about Flux is to build things in tandem with reading about it (and finding nice developers who can guide you)!

Day 6 - JSON-LD # Back to top toggle

JSON, or JavaScript Object Notation, is a simple language that represents objects on the Web and facilitates data exchange. LD, or Linked Data, allows for the expression of critical data on a site, and for it to be shared across sites. I first heard of it at Beyond Tellerrand in Düsseldorf on May 7th, during a talk about web annotations by Lyza Danger Gardner. JSON-LD allows expressions of linked data in JavaScript. It's like grammar for describing strutured data. It can be thought of as JSON, but with added semantics. And it can be easily implemented into existing JSON structures. Here's some example JSON:

{
    "name": "Amber Wilson",
    "homepage": "https://amberwilson.co.uk",
    "picture": "https://twitter.com/account/
    profil_image/ambrwlsn90"
}
Here is similar information in JSON-LD format:
{
    "@context": {
        "xsd": "http://www.w3c.org/2001/XMLSchema#",
        "foaf": "http://xmlns.com/foaf/0.1/",
    },
    "@id": "http://me.amberwilson.co.uk",
    "@type": "foaf:Person",
    "foaf:name": "Amber Wilson",
}

Above, we see that context can be added to data. foaf stands for "friend of a friend" (see here), which deals with people-related terms. id and type, like context, assist in making our data shareable and semantic.

The concept of JSON-LD is simple, but using it can take getting used to. For more in-depth information, see here.

Day 7 - CSS Layout # Back to top toggle

CSS layout is something that amazes and confuses me at the same time. There seem to be so many approaches (e.g. floats, flexbox, grid), and so many frameworks (way too many to mention). The paradox of choice seems to apply here.

I love hearing from people about CSS layout, and I was lucky to hear Miriam Suzanne talk about it at Beyond Tellerrand (check out the awesome layout on her site). The message she gave was to use CSS grid, and provide fallbacks for browsers that aren't grid-compatible. She reasons that as grid makes layouts so easy (and naturally responsive), that there is time to re-create fallback layouts, which allows more creative control.

One thing I really like about CSS layouts is that they aren't designed to be used in isolation. On the contrary, you can mix and match them. A grid item can become a flex container, and a flex item can become a grid. You can even use floats with flexbox and grid.

I am half-way through Wes Bos's CSS grid course and already have ideas I am excited to make come to life using grid. There are looots of great posts and articles out there by people who have had tonnes of fun and learned loads by using grid. I really recommend finding some and making some stuff!

Day 8 - Debugging # Back to top toggle

Recently at work, I've watched other developers use console.log a lot in code to find desired values given by certain functions. I am often still confused where to put console.log, and it is definitely not the only way to debug, so I've also begun to use the developer tools JavaScript debugger in Firefox and Chrome. These tools allow you to pause the execution of your code, and walk through it to help you find bugs.

The debugger can do a lot, and it'd take a much longer post to walk through this tool's UI, so I'll mention four of the most commonly used debugging methods here.

  • Step over code
    • Steps over a function that doesn't contain a bug and runs its code
  • Step into code
    • Steps inside a function and allows you to run each part separately
  • Step out of code
    • Steps out of a function you are inside, and runs its code
  • Resume execution of code
    • Runs all code up until a specified breakpoint, which can be set at any point

Debugging is something developers have to be really good at. So don't be scared to do it! Or, be scared but do it anyway, you'll get better :)

Check out the docs on the Firefox debugger and the Chrome debugger. Lots of great info there to help you get started. Also check out this article from Peter Lyons. He explains debugging of both front-end and back-end JavaScript code.

Also, check this out - an honest post about how even experienced devs find it hard to debug.

Day 9 - Readable Code # Back to top toggle

There are so many books, articles, and videos about how to make code readable, so I'll keep this short and from my perspective (as a new developer who works mainly with JavaScript).

  • Code style of your project. This is specific to each project and covers things like indentation, levels of nesting, naming, spacing etc. There are some nice tools to help with this - for example ESLint that you can configure to autoformat your code to your specified style upon file save.
  • Structure. This is about how you organise your code and files in a project. I have been taught the benefit of abstracting and modularising code, making it easier to tell what each part does and easier to test. In React, I've been writing components that are either presentational (how things look) or containers (how things work). Between different projects and programming languages, there are many, many ways to structure code well, and opinions tend to differ.
  • Commenting. There are three ways I've been doing this - either in my CSS, or in one of two ways (single-line with // or the JSDoc way) in my JS. The most important way to comment CSS is when magic numbers, i.e. seemingly random numbers that don't use pre-defined mixins or seem to relate to the rest of the code, are present. Leaving a note about these numbers can help other developers (or yourself a few months later) understand why the CSS is written that way. An important thing to remember when commenting JS code is that comments should state what the expected results of the code (e.g. a function) is, and not a description of what the code is doing.
  • Naming. This is well-known as one of the hardest things in programming. But it pays off big time. It helps developers get as close a possible to the coveted self-documenting code that doesn't need any comments (although I think no comments at all is probably a bad thing). I feel some developers keep function and variable names short in order to make their code look cleaner and keep file sizes small. However, on my latest project at work, without some of the really long and descriptive naming going on, I'd have a much harder time understanding the complex codebase.
These are the four areas around readable code that popped into my mind. There are definitely more, and there are so many resources on this. Go check 'em out, and dicsuss them with people! I know I'll continue to do both those things for a long time to come.

Day 10 - Strings # Back to top toggle

  • A sequence containing some letters, numbers or symbols.
  • Have available methods and properties.
  • Can be stored in variables.
  • Sit between either single quotes (' '), double quotes (" "), or backticks ( ` `).
  • Can be concatenated (stuck together) with the + operator, or with backticks (template strings) in ES6.
  • Template strings, or template literals, can take any valid JavaScript expression, allowing dynamic strings.
  • Can contain special characters, such as quotation marks, as long as they are escaped - e.g. "She'\ll be coming '\round the mountain when she comes".
  • There's no need to escape dissimilar quote marks. For example: "This 'is' fine". This is probably why we tend to favour double quotes in HTML attribute values, and singles in JS (since it allows you to create some innerHTML without the need for escaping).
  • When using template literals, you don't need to escape ' or " ... and `this "is" 'also' fine`
  • Is either a string primitive - immutable and more common, e.g. const stringPrimitive = "Hello, I am a string."; .
  • Or a string object - const stringObject = new String("Hello, I am a string.");
  • The typeof operator is used to determine if a string's type is string or object.
  • Each character is indexed and can be accessed by an index number using square bracket notation (e.g. "Hello World" - myString[0] outputs "H").
  • Similar methods to the one above include: charAt(), indexOf(), lastIndexOf(), slice().
  • Other common methods and properties are: length, toUpperCase(), toLowerCase(), split(), trim(), replace().

This list is meant as a quick and basic introduction to the magical world of JavaScript strings. If there's something you'd like me to add, let me know!

Many thanks to my good friend Mark for suggestiong additions :)

Day 11 - Emmet # Back to top toggle

Emmet provides a really useful way to make developing easier. It improves the developer experience™. I only discovered it recently but love it already. It originated as Zen Coding about ten years ago. There are a few uses (see official docs), but I'll focus on the amazing abbreviation and snippet expansion feature.

In your HTML, say you need 100 divs. And each should have a class of teddybear. Typing these out by hand might be boring. With Emmet, you can write div*100.teddybear (then press 'tab'). Or if you need each class to be item1, item2, etc. then you can write div.item$*3. There are also HTML elements that get handily created with relevent attributes - try typing a or img. See one of the original articles on Emmet here for more examples. You can download it or check if it comes built-in with your text editor of choice - I use VSCode and found Emmet was ready for use!

Emmet also features CSS selector expansion which allows you to type abbreviated selectors that are expanded when you press 'tab'. It can also automatically add vendor prefixes for you. Try and see how many abbreviations you can guess here ;)

Day 12 - Testing # Back to top toggle

Today at work, we talked about test automation. One of the developers mentioned this quote:

We cannot rely on mass inspection to improve quality, though there are times when 100 percent inspection is necessary. As Harold S. Dodge said many years ago, ‘You cannot inspect quality into a product.’ The quality is there or it isn’t by the time it’s inspected. - William E. Deming in Out of the Crisis

Therefore we cannot rely on creating features in a hurry, throwing them over the fence and then expecting our applications to work well and without bugs. To instil quality from the start of a feature, there should be tests for it.

Automated testing helps with this. Pre-commit hooks can be used when deploying builds so that errors are caught and addressed early. Unit tests can be run using pre-commit hooks - see my post on unit tests here. However, there is a fine line between having too many automated tests, e.g. end-to-end tests that take too long to run with each build, and not having enough. Some companies run quicker unit tests on each build, and then run end-to-end tests as a nightly build.

Please see the image below for one of many examples of the testing pyramid if you are confused when I mention unit tests or end-to-end (UI) tests:

The Testing Pyramid

Manual testing is important too. It is usually done by QA engineers, and helps reveal edge cases that automated tests do not catch. As one developer at my work said, these tests are like the cherry on top of the testing pyramid.

Day 13 - Object Literals # Back to top toggle

I didn't learn about these at work but rather from a video on the JavaScript reduce function by the wonderful MPJ.

Object literals are a data structure that can be used in JavaScript. I really like seeing how data can be organised and object literals do this really nice and tidily. Here's an example:

var cat = {
    myCat: 'Tabby',
    getCat: catTypes('Siamese')
}

The above code is an alteration of the MDN example. I found MDN's explanation of object literals a little mechanical (compared to other resources I found), but it does give quite a clear portrayal of how flexible object literals can be. For instance, the typical combination of a key (myCat), value (Tabby) pair can be accessed and used in other places in your code, without these values polluting the global scope*. You can use the catTypes function like so:

function catTypes(type) {
    if (type !== 'Siamese') {
        return type;
    } else {
        return "Many " + type + " cats have blue eyes.";
    }
}

console.log(cat.getCat) // Siamese

If this was not exciting enough, there are many other data types (not only functions) that can be organised using object literals - e.g. array literals (see an example of this in MPJ's video), nested object literals, numbers, any string, etc.

My friend Mark also informed me that an object can contain itself (which is not recommend because it breaks JSON.stringify)!

Of course as with any programming language, there are rules. Some of these are that a colon separates the key from the value, a comma separates key-value pairs, there shouldn't be a comma after the last value-pair (well, it's fine to have a dangling comma, but many style guides don't want you to do it), etc.

For more rules and when to use, check out this nice post, and the MDN page.

I haven't had much of a chance to use object literals in the wild yet, but I hope to soon. After I have, I hope to write an updated post that describes my new insights.

* An object (literal) can be used like a namespace to avoid polluting the global object, but there's still the reference of the object attached to global. If you want to completely eliminate variables polluting the global object as fields, then IIFEs are for you. Some modules are also isolated from global. So, object literals limit pollution through namespacing, but do not entirely eliminate it. (Thanks, Mark, for the information).

Day 14 - Ternary Operator # Back to top toggle

This is one of my favourite things in JavaScript. Not only is it simple and easy to use but it's also applicable to lots of situations and it can replace more verbose syntax (like if statements). It looks something like this:

const hoursOfSleep = 5;
const timeForSleep = (hoursOfSleep < 8) ? 
    "Yup, no more phone for you" : 
    "Ah nah, a few more minutes of phone time won't hurt"; 

Notice the ? and the :

These are the important parts.

If the condition (in this case hoursOfSleep) in front of the question mark evaluates to true, the value of the first expression before the colon is returned. If the condition in front of the question mark evaluates to false, the value of the second expression after the colon is returned. As you can see, if you have had less than 8 hours of sleep, you shouldn't be using your phone.

Ternary operators are really flexible and can be used in a number of ways. You can stack them together:

const catsRule = true,
const dogsDrool = false,
const catDog = catsRule ? 
    (dogsDrool ? "Let's all live in harmony": "Both cats and dogs drool") :
    (dogsDrool ? "Dogs are cool, nearly as cool as cats" : "Dogs and cats can be friends");
    

This outputs "Both cats and dogs drool", and it's also total nonsense but I hope you had fun staring at it and trying to figure it out. You don't even need to use the parentheses, and can also use multiple statements separated by commas. You can return statements in functions. You can use them in place of bulky if/else statements with much nicer-to-read code. The question mark means if and the colon means else.

I use ternary operators at work all the time. I hope you enjoy them as much as I do. Check out the MDN page for some examples. This post is lovely too.

Day 15 - Array Prototype Methods # Back to top toggle

Array.prototype methods are super useful for transforming array data and cover a lot of common needs in modern applications! They are a form of higher-order function (HOC), which are functions that take another function as their argument, or return one as a result. A good way to view functions is as values, because then it's easier to imagine being able to pass them around. For me, they've been a great introduction into the world of functional programming. In functional programming, the functions you create are pure, i.e. they have no side effects, rely on the input you give them, and will always produce the same output given the same input.

So, I use array methods more and more at work and they are definitely a pleasure to work with! There are quite a lot of them (I think around 50), but there are some more frequently used ones that cover most use cases, such as sort(), map(), filter(), and reduce(). I was inspired to write about them after reading this post by Angelos Chalaris! Please check out his post because there are great examples & explanations in there!

Of course, since I like them so much, I wanted to give an example here. The one I used most at work is map() but I didn't choose it because I gave an example of it in Day 2 :) As a side note, if you look carefully at the example in Day 2's lesson, you'll see how the elements array takes the map function, which in turn takes a function as its input, and returns a value based on the input. Below, I decided to create an example of reduce().

const initialCatRating = [10, 10, 10];
const accurateCatRating = initialCatRating.reduce((total, amount) => {
    total.push(amount * 2);
    return total;
}, []);

accurateCatRating // [20, 20, 20]

This example shows one of the many things reduce can do - alter values in an array, and push the altered values into a new array! This means a brand new array is returned, rather than altering the initial array. Let me explain what's happening:

There is an initialCatRating variable, which shows ratings of cats out of ten. In the accurateCatRating variable, reduce() is called on initialCatRating.

The first argument in reduce() is a callback function (see this in pink above). The callback takes at least two and up to four arguments (accumulator, currentValue, currentIndex, array). The above example has taken two - total and amount, which are actually accumulator and currentValue. Naming doesn't matter here, but order does.

The second argument in reduce() is initialValue, which is optional. In the above example, initialValue is an empty array. The callback only operates on every element in an array when initialValue is present, so for the above example it is not optional.

Putting the callback and initialValue together allows reduce() to take each element in the given array and operate on it, then push the returned values (using push() - another array method) into a new array.

Of course, to make it re-usable, you can extract the callback function from the above example into something like:

const doubleMyValue = (total, amount) => {
    total.push(amount * 2);
    return total;
};

Then, it can be put straight into reduce() (as an argument), to read:

const initialCatRating = [10, 10, 10];
const accurateCatRating = initialCatRating.reduce(doubleMyValue , []);

accurateCatRating // [20, 20, 20]
    

The reduce() callback above is actually not a pure function, because it modifies one of its parameters. To keep reduce() pure/functional, the callback can only take primitive values. See the MDN article for examples. And see some more examples here. Try some Array.prototype methods out in your browser console! :)