Angular provider scopes explained

Reading Time: 8 minutes

Services are one of the building blocks of Angular you will see in every Angular application. Their main purpose is to increase modularity and reusability or in other words to separate a component’s view-related logic from any other kind of processing. Usually, components are delegating various tasks to services like fetching data from a server, validating user input, logging, etc. By defining these kinds of tasks in injectable services, we are making them available to any component.

One service is just a TypeScript class that has @Injectable decorator attached. This decorator makes service available to Angular’s Dependency Injection (DI) mechanism which is built into the Angular framework.

import { Injectable } from '@angular/core';

@Injectable()
export class ExampleService {

  constructor() { }
}

When components like consumers reference one service, Angular DI provides an instance from that service.

import { Component } from '@angular/core';
import {ExampleService} from "./services/example.service";

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  // Reference to ExampleService
  constructor(private exampleService: ExampleService) {
  }
}
Source: https://memegenerator.net/instance/55044567/futurama-fry-wait-a-second

How the Angular DI knows how many instances of one service to provide? Is it always just one? How can we tell Angular how many instances to create?

The answer is: provider scopes.

Before we dive into provider scopes and ways of providing service in Angular, let’s define module injector (ModuleInjector) hierarchies.

Visualization of module injector hierarchy

On the image above we can notice the ModuleInjector hierarchy:

  • Platform Module injector – the top module injector, usually used for special things like DomSanitizer
  • Root Module injector – main injector and it is the place for all eagerly loaded module providers
  • Lazy Modules injectors – all lazy-loaded modules are creating separate child injector from the root injector

These module injectors are used from Angular Dependency Injection during creating instances of services.

Now it’s time to dive into provider scopes and how everything works in practice.

There are five provider scopes in Angular:

  • Module scope
  • Component scope
  • Root scope
  • Platform scope
  • ‘any’ injector

Module scope provider

When the service is registered in providers array in one @NgModule, we say its service in the module.

...
import {ExampleService} from "./services/example.service";

@NgModule({
  ...
  providers: [ExampleService]
})
export class AppModule { }

There are two different scenarios to cover when one service is provided in Angular Module:

  • Service is provided in the root module or in an eagerly loaded module – The Angular DI mechanism will use a Root Module Injector and will create one service instance which will be shared between the root module and eagerly loaded modules (all providers from all imported modules are merged into the root injector)
  • Service is provided in a lazy-loaded module – The Angular DI mechanism will use Lazy Module (child injector) and will create one instance for every different lazy-loaded module where it is provided

Component scope provider

One service can be provided also in @Component, registering should be also made in the providers’ array. This means if the service is provided and referenced in a particular component, then for that component and all their children will be created one separate instance of the service, not depending on other providers. This is applied per instance of the component, which in practice means if that component has 3 instances, 3 instances of the service will be created.

import { Component } from '@angular/core';
import {ExampleService} from "./services/example.service";

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
  providers: [ExampleService]
})
export class AppComponent {
  // Reference to ExampleService
  constructor(private exampleService: ExampleService) {
  }
}

The component scope provider is the most specific and Angular starts searching for providers at the first from component and then goes up by hierarchy until it finds it or to the last Platform Module Injector.

Root scope provider

Starting from Angular version 6 it is introduced the possibility to provide a service without registering in @NgModule or @Component, instead of that the providing info should be placed inside @Injectable decorator with providedIn: ‘root’ option.

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class ExampleService {

  constructor() { }
}

With this kind of providing services, they are provided in Root Module Injector (typically called AppModule) and Angular DI creates a single, shared instance of the service and injects the same instance in every reference. Actually, the service acts like Singleton (Singleton pattern). This is valid if it is referenced in lazy and non-lazy modules too, they all receive the same instance.

Visualization where services with providedIn: ‘root’ option will be provided

The other benefit of this kind of registering is the tree-shaking option for optimizing the app bundle size, if it turns out that the service is not referenced anywhere, Angular DI does not register the service into the root injector at all.

Platform scope provider

Starting from Angular 9, one of the two new ways of providing services is providedIn: ‘platform’ option.

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'platform'
})
export class ExampleService {

  constructor() { }
}

When one service is defined with providedIn: ‘platform’ it means that the service will be provided in Platform Module Injector and it acts like Singleton for all applications, also all lazy modules will use the instance from the platform.

Visualization where services with providedIn: ‘platform’ option will be provided

This kind of provider looks similar to ‘root’, but the key difference is only when we are running multiple Angular applications in the same window. Every application that runs in the window will have a separate Root Module Injector, but they will both share the Platform Module Injector. In practice this means, we are sharing the services over the application boundaries.

‘any’ Injector

This kind of providing services is the second newly added option starting from Angular version 9, the syntax is providedIn: ‘any’.

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'any'
})
export class ExampleService {

  constructor() { }
}

Providing a service like this means every service will be provided in every module where it is used. So one service can have more than one instance, depending on its usages. The rule here is that every lazy-loaded module will have its own instance, and all eagerly loaded modules will share one instance provided by the Root Module Injector.

Visualization where services with providedIn: ‘any’ option will be provided

Summary

When Angular finds one service referenced in some component, in order to create an instance or use one of the created ones Angular starts looking for a provider in the following order:

  1. Component providers
  2. Module providers
  3. Root providers
  4. Looks for providedIn: ‘any’ injector and decides the number of instances
  5. Platform providers

Component scope provider option mostly will be used in some edge cases for example when we have dynamically created tabs, all have the same component like root, but every tab should have its own state, then we added one service in providers list of the tab root component and for every tab, we will have a different instance.

Module scope provider option was the default option for providing services before Angular 6, nowadays it is also very much used when we want one instance per lazy-loaded module, but as we exposed previously starting from Angular 9 this can be achieved with providedIn: ‘any’ option.

providedIn: ‘root’ this option is the default option when we create a new injectable service in Angular and most of the time we will need tree-shakable singleton services within an application.

providedIn: ‘any’ this is a very helpful option if we want to make sure that one service is singleton within module boundaries.

providedIn: ‘platform’ this option will be mostly used when we want singleton service within several Angular applications which run in the same window.

Core features of next-generation JavaScript

Reading Time: 4 minutes

Since we are working with the modern frameworks or libraries of course it is strongly recommended to use the next-generation JS features. Let’s take an overview of the most used features together.

As you know we do not use anymore var but instead, we are using let or const, depends on the case scenario.

Let

Let is a block-scoped local variable which makes the variable limited to the scope of the block statement.

Example:

function varTest() {
  var x = 1;
  {
    var x = 2;  // same variable!
    console.log(x);  // 2
  }
  console.log(x);  // 2
}

function letTest() {
  let x = 1;
  {
    let x = 2;  // different variable
    console.log(x);  // 2
  }
  console.log(x);  // 1
}

Const

Similar like let, const is also block-scoped, but here the difference is that a constant cannot be reassigned or redeclared. So, from here we can say they are read-only objects.
What is interesting here is that the value is mutable. That means direct reassignment is not allowed but changing object properties.

const ctest = 1;
ctest = 2;	// results with error

const cobj = {
    name: "Dimitar"
}
cobj.name = "Test"; // no errors

Arrow functions

Arrow functions are a replacement of the standard known normal functions which give us new shorter syntax and different behaviour of the scope where:

  • When calling normal functions this refers to the object that calls the function
  • When calling arrow function this refers to the outer function that surrounds the inner function
function thisTest() {
    let that = this
    this.prop1 = 0;

    setInterval(function growUp() {
        this.prop1++;
		that.prop1++;
        console.log(this.prop1)
        console.log(that.prop1)
    }, 1000)
}

function thisTest1() {
    let that = this
    this.prop1 = 0;

    setInterval(() => {
        console.log(this.prop1)
        console.log(that.prop1)
        this.prop1++;
		that.prop1++;
    }, 1000)
}

let thisNormal = new thisTest();
/* Prints:
undefined 0
NaN 1
NaN 2
NaN 3
...
*/
let thisArrow = new thisTest1();
/* Prints:
0 0
2 2
4 4
6 6
...
*/

Exports & Imports

In every modern project, we are splitting the code of our project in different modules, where those modules keep our code module focused and manageable. So, the communication between the modules, we maintain with imports (used to get access to a module) and exports (used to make it available to other modules).

From here we can export or import everything, from constants to classes by having unlimited exports and imports.

Exports:
export let numbers = [1, 2, 3 , 4, 5]
export class User {
	constructor(name) {
		this.name = name
}
}

Imports:
import { User } from ‘./…’

Classes

…are used to replace constructor functions and provide better readability.

class P {
    constructor() {
        name = "Dime"
    }
}

const p = new P();
p.name;


replaced with

class P2 {
     constructor () {
         this.name = 'Max';
     }
}

const p2 = new P2();
console.log(p2.name);

class Human {
    species = 'human';
}

class Person extends Human {
    name = 'Max';
    printMyName = () => {
        console.log(this.name);
    }
}

const person = new Person();
person.printMyName();
console.log(person.species);

Spread operator

Spread operator allows us to pull elements out of an array or pull the properties of an object. The spread operator is very useful because it is a lot used to help us clone arrays and objects with different reference.

const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5];

const obj1 = {
    name: "Dime"
}

const obj2 = {
    ...obj1,
    age: 26
}

const obj3 = {...obj1};
const obj4 = obj1;
obj1 === obj3;  // false
obj1 === obj4; // true

Destructuring

The last next-generation feature I am going to cover is destructuring. Destructuring allows us to easily access the values of arrays and objects and assign them to variables. This is mostly used when we are working with function arguments when we are calling with the whole object but getting the properties that we only need.

const arr = [1, 2, 3];
const [a1, a2] = arr;

const obj = {
    name: "Dime",
    age: 26
}

const {name} = obj;

const printValue = (obj) => {
    console.log(obj.name);
}

const printValue1 = ({name}) => {
    console.log(name);
}

printValue({name: "Dime", age: 26});
printValue1({name: "Dime", age: 26});

Conclusion

As we can see next generation is already here and I strongly believe that in near future in the modern projects there won’t be tolerated non-next-generation JavaScript code.
So don’t hesitate, simply just try it and enjoy the next-generation JavaScript features.

Using the Vue3’s composition API in Vue2

Reading Time: 4 minutes

Vue3 is officially out since September 18 and along with it comes the composition API which is replacing the old options API. The new composition is defined as a set of additive, function-based APIs that allow the flexible composition of component logic.

We are introduced to the composition API because with the old options API as the component grows the readability of the components was not quite pleasant or comfortable and was starting to get messy, the code reuse patterns had some drawbacks, the support for TypeScript was limited etc.
The visual comparison of both APIs look something like this:

First, we must install @vue/composition-api via Vue.use() before using other APIs.
Import the VueCompositionApi:

import Vue from 'vue'
import VueCompositionApi from '@vue/composition-api'

Register the plugin:

Vue.use(VueCompositionApi)

And then we are ready to start.

So, the new API must contain the setup() function which serves as the entry point for using the composition API inside the components. setup() is called before the beforeCreate hook. The component would look like this:

<template>
    <div> {{ note }} </div>
    <div> {{ data.count }} </div>
</template>

<script>
import { ref, computed, reactive, onMounted } from '@vue/composition-api'

export default {
  setup() {
    const notes = ref([])
    async function getData() {
      notes.value = await DataService.getNotesData()
    }

    const data = reactive({
      count: 0,
      actions: ['firstAction', 'secondAction', 'thirdAction'],
      object: {
        foo: 'bar'
      }
    })
    const computedData = computed(() => notes.value)
    
    onMounted(() => {
      getData()
    }

    return {
      ...toRefs(data),
      notes,
      computedData
    }
  }
}
</script>

In the code above we can see the structure of the new API. We have the setup() function, which is exported in the script tag.
Inside the setup function we can see several familiar properties.

const notes = ref([])

This is initializing a property inside the setup function scope. On this property, we must add ref if we want to make it reactive, which means if we don’t add the ref and we make a change to that variable, the change won’t be reflected in the DOM. This is the same as initializing variable in the data() in Vue2:

data() {
  return {
    notes: []
  }
}

As we can see we do not have the method section for creating functions, instead we define the functions in the setup(). After that, the method is used in the mounted hook which is a bit different than the one in the options API.

Some of the hooks were removed, but almost all of them are available in a similar form.

  • beforeCreate -> use setup()
  • created -> use setup()
  • beforeMount -> onBeforeMount
  • mounted -> onMounted
  • beforeUpdate -> onBeforeUpdate
  • updated -> onUpdated
  • beforeDestroy -> onBeforeUnmount
  • destroyed -> onUnmounted
  • activated -> onActivated
  • deactivated -> onDeactivated
  • errorCaptured -> onErrorCaptured

In addition, two new debug hooks were added to the composition API:

  • onRenderTracked
  • onRenderTriggered

Computed and watch are still available. In the code above we can see how computed is used to return the notes values.

Reactive() is similar to ref() and if we want to create a reactive object we can still use ref(). But underneath the hood, it’s just calling reactive(). On the other side, reactive() will not work with primitive values. It takes an object and returns a reactive proxy of the original. The big difference is when you want to access data defined using reactive(), for example, if we want to use the count, we must do it like:

<div> {{ data.count }} </div>

One very important thing is to convert a reactive object to plain object is using the toRefs and return the data like in the component:

return {
  ...toRefs(data)
}

This is just a small piece of the cake, only something to begin with using the composition API in Vue2 application. For more, you can visit the documentation on the following link.

JavaScript Best Practices for Readable and Maintainable Code

Reading Time: 4 minutes

Let’s have a look at some coding standards that can help with:

  • Keep the code consistent
  • Easier to read and understand
  • Easier to maintain
  • Easier to refactor

These coding standards are my own personal opinion that can help with the above points using what I have learned and experienced while developing and reviewing other developers code.

Variables

Always use ‘const’ & ‘let’ over ‘var’

Using const helps readability as developers know it can’t be reassigned.
var and let are both used for variable declaration in javascript but the difference between them is that var is function scoped and let is block scoped. It is too much to get into detail here maybe I will write another post for that.

Avoid using global variables

Minimize the use of global variables. Global variables are a terribly bad idea. The problem with global variables and functions is that they can be overwritten by other scripts.

Naming variables

Always try to come up with names that make sense and are not too long. Naming variables may be the hardest thing in coding.
let should be camelCase. const, if it is at the top of the file it should be SNAKE_CASE (All Caps). If it is not at the top then it should be camelCase.

API Calls

Pick a method and stick with it

By method I mean one of the below:

  • XMLHttpRequest
  • fetch
  • Axios
  • jQuery

So far Axios and fetch are the most preferred way to go with. The benefit of using Axios is that it has wide browser support. Even IE11 can run Axios.

Make the calls reusable

Instead of just having the calls everywhere in the code it is good to have modules for your API calls. This way it becomes easier to refactor. If something changes in the API you will have to change it only once.

Dom Manipulation

Use CSS classes over adding styles

For example we have some basic forms here:

<form>
  <input type='text' required>
  <button type='submit'>
    Submit
  </button>
</form>

Along with the following JavaScript code:

const input = document.querySelector('input');
const form = document.querySelector('form');
form.onsubmit = (e) => {
  e.preventDefault();
}
input.oninvalid = () => {
  input.style.borderColor = 'red';
  input.style.borderStyle = 'solid';
  input.style.borderWidth = '1px';
}

Instead of adding inline style like the above example, it is much cleaner to add CSS class to the input field like in the example below:

const input = document.querySelector('input');
const form = document.querySelector('form');
form.onsubmit = (e) => {
  e.preventDefault();
}
input.oninvalid = () => {
  input.className = 'invalid';
}
// CSS
.invalid {
  border: 1px solid red;
}

Accessing the DOM tree

Accessing the DOM tree is a quite expensive operation this is the bottleneck of JavaScript in terms of performance. Therefore, we must strive to minimize the operations of accessing the DOM tree.

Example:

// BAD
let padding = document.getElementById("content").style.padding
let margin = document.getElementById("content").style.margin;

//GOOD
let style = document.getElementById("content").style
let padding = style.padding
let margin = style.margin

Functions

Use ES6 arrow functions where possible

Arrow functions are a more concise syntax for a writing function expression. They’re are anonymous and change the way this binds in functions.

//BAD
var multiply = function(a, b) {
  return a* b;
}

//GOOD
const multiply = (a, b) => a * b

 Naming functions

Functions should be camelCase and should have descriptive names:

//BAD
const sMail = () => {
  //...
};
const sendmail = () => {
  //...
};

//GOOD
const sendMail = () => {
  //...
};

Functions should only do one thing

This is one of the most important rules in programming. When your function does more than one thing, it is harder to test and read. When you isolate a function to just one action, it can be refactored easily and your code will be read much much cleaner.

//BAD
const notifyListeners = listeners => {
  listeners.forEach(listener => {
    const listenerRecord = database.lookup(listener);
    if (listenerRecord.isActive()) {
      notify(listener);
    }
  });
}
//GOOD
const notifyActiveListeners = listeners => {
  listeners.filter(isListenerActive).forEach(notify);
}

function isListenerActive(listener) {
  const listenerRecord = database.lookup(listener);
  return listenerRecord.isActive();
}

Conclusion

Coding standards in any language can really help with the readability and the maintainability of an application. The main point is to be consistent as they really help scale up an application in a clean way.

If you take this advice, it will bring your read and maintainability to the next level. The next time you need to address an issue or implement a feature request, your journey will be fast and seamless.

Server-side rendering with Nuxt.js

Reading Time: 5 minutes

What is server-side rendering

By default, modern JS frameworks produce and manipulate DOM in the browser as an output. But, it is possible to render the same codebase into HTML strings on the server and send them to the browser and finally compile the static markup into a fully working application on the client-side. A server-rendered application can also be considered isomorphic or universal, in the sense that the majority of your code runs on both the server and the client.

Trade-offs when using SSR

  • Development constraints
  • Build setup, deployment requirements
  • Server-side load

Advantages when using SSR

  • Better SEO
  • Faster time to content

Nuxt.js

Nuxt is a framework based on Vue.js, Node.js, Webpack and Babel. It is free and open-source and we can use it to create various applications from static landing pages to complex enterprise-ready web solutions.

Supports 3 modes of working:

  1. Server-Rendered (Universal SSR)
  2. Single Page Applications (SPA)
  3. Static-Generated (Pre Rendering)

Some of the features Nuxt provides:

  • Write Vue Files (*.vue)
  • Automatic Code Splitting
  • Server-Side Rendering
  • Powerful Routing System with Asynchronous Data
  • Static File Serving
  • ES2015+ Transpilation
  • Bundling and minifying of your JS & CSS
  • Managing element
  • Hot module replacement in Development
  • Pre-processor: Sass, Less, Stylus, etc.
  • HTTP/2 push headers ready
  • Extending with Modular architecture

Project structure

Here we have the project structure that Nuxt provides out of the box. The pages, middleware, plugins and layouts directories are framework-specific and we’ll briefly explain their purpose.

The Nuxt community has added great README.md files into each directory with links to the documentation.

The layouts directory defines all of the layouts that our application can use. This is a great place to add shared global components that are used across the application like the header and footer for example. By default, the template that is used for .vue files in the pages directory is default.vue. It is needed to inject all of the page’s components, text, assets, and data.

Pages is the only required directory. All Vue components in this directory are automatically added to the vue-router based on their filenames and the directory structure. We can have dynamic routes by adding an underscore (_) to a directory or a .vue file.

/pages
---/categories
------/_category_id
------/products
---------/_product_id

// The structure above generates a router config that will provide 
// a route for /categories/1/products/3 for example

Middleware is a function that can be executed before rendering a page or layout. There is a variety of reasons we may want to do so. Route guarding is a popular use where we could check the Vuex store for a valid login or validate some params (instead of using the validate method on the component itself). Another use for middleware can be to generate dynamic breadcrumbs based on the route and params. These functions can be asynchronous, meaning nothing will be shown to the user until the middleware is resolved.

The plugins directory allows us to register Vue plugins before the application is created. This allows the plugin to be shared throughout our app on the Vue instance and be accessible in any component. Most major plugins have a Nuxt version that can be easily registered to the Vue instance by following their docs. However, there will be circumstances when we will have to develop a plugin or need to adapt to an existing plugin.

Nuxt’s supercharged components

Nuxt’s page components have extra methods attached to them that we can use to provide additional functionality. The main ones we would use in a project will be the asyncData and fetch methods. Both are very similar in concept, they run asynchronously before the component is generated, and they can be used to populate the data of a component and the store. They also enable the page to be fully rendered on the server before sending it to the client even when we have to wait for some database or API call.

Summary

There’s a lot to cover with Nuxt and server-side rendering, this post aims to provide a general overview of the framework, why server-side rendering is important and how we can scaffold our next web application using Nuxt.

Before using SSR though, we should ask whether we actually need it. Generally, it depends on how important time to content is for the application. If we are building an internal dashboard where an extra few hundred milliseconds on initial load isn’t an issue, SSR wouldn’t be needed. However, in applications where time to content is critical, SSR can help us achieve the best possible performance.

This is a starter Nuxt application which showcases examples of the features mentioned in the post if you have any comments or feedback let us know.
nuxt-ssr-example

Thanks for reading!

Lifecycle hooks in Vue.js

Reading Time: 3 minutes

In this post we’ll be doing an overview of lifecycle hooks in Vue.js.

Each Vue application first creates a Vue instance, with the Vue function:

var vm = new Vue({
  router,
  render: function (createElement) {
    return createElement(App)
  }
}).$mount('#app')

This Vue instance during its initialization goes through several phases and it exposes some properties and methods in each phase. This is an example of Vue using the template method behavioural design pattern.

The methods which run by default in this process of creating and updating the DOM are called lifecycle hooks and using them properly allows easy access to a behind the scenes overview of how the library works.

Below we can see a simple diagram showcasing all methods in one instance.

We can see that we have 8 methods that we can split into 4 phases in an application’s lifecycle.

  • Creation or initialization hooks (beforeCreate, created)
  • Mounting or DOM insertion hooks (beforeMount, mounted)
  • Updating hooks (beforeUpdate, updated)
  • Destroying hooks (beforeDestroy, destroyed)

Creation hooks

beforeCreate is the first hook that gets called in a Vue component, it has no access to the components reactive data and events as they haven’t been initialized yet. It’s good to use this hook for non-reactive data.
The created hook has access to the components events and reactive data and state. The DOM and $el properties are still not available. This hook is usually used to perform API calls and store the response.

Mounting hooks

The next lifecycle hook to be called is beforeMount and it happens right before the component is mounted on the DOM. Here is our last opportunity to perform operations before the DOM gets rendered.
Mounted is called right after and now the DOM is available. This is a good place to add third-party integrations like charts, Google Maps etc, which interact directly with the DOM.

mounted() {
  console.log('This is the DOM instance', this.$el)
  this.$nextTick(function() {
    console.log('Child components have now been loaded')
  }
}

Updating hooks

beforeUpdate and updated are the two hooks that are called each time a reactive property is changed. The data in beforeUpdate holds the previous values of the property, while after updated runs, the instance has finished re-rendering.

beforeUpdate () {
  console.log('before update called')
},
updated () {
  console.log('update finished')
}

Destroying hooks

When beforeDestroy, we can still mutate the state and the instance is still functional. Here we can do some last moment data mutation before the instance is destroyed.
When destroy is called, the Vue instance does not exist anymore. All directives, event listeners have been removed and child components have been destroyed.

beforeDestroy () {
  console.log('before destroy called')
},
destroyed () {
  console.log('destroyed')
}

I hope this provides a good overview of the lifecycle hooks in a Vue application. For more information, refer to the official docs here.

JavaScript loop and object iteration (optimization)

Reading Time: 3 minutes

Nowadays, it’s interesting that loops become part of our life as developers and we use them at least one time a day. Because of that, one day I decided to investigate and go deeper into JavaScript loops, where I found very interesting things and if I do not share them with you, I am going to feel guilty.

Before you continue reading, I would strongly recommend you to read my previous blog which I believe you will find very useful to create a full picture of the loops. So, go on and read it.

Object properties iteration

Let’s first analyze object iteration and suppose that we have an object, something like:

var obj = {
    property1: 1,
    property2: 2,
    …
}

First, what comes to our mind is to iterate them with the standard for each iteration:

for (var prop in obj) {
    console.log(prop);
}

In this case, we are going to iterate through the object properties but is it the correct way? The answer is yes and no, depends on your needs. Another way to iterate trough is to exclude all inherited properties, which in some case we do not need. So, we can exclude them by using the JavaScript method hasOwnProperty(). You can find an explanation about in operator and hasOwnProperty() in my previous blog.

Since we learned some object optimization/improvements/usage, now the question is, can we really do an optimization?
The answer is yes. Before I am going to show you how we can do that, let’s spend some time on the loops.

Loop iteration

In order to continue the previous example, I will continue explaining the loops with object iteration (of course you can test it with a list of integers like the speed test examples or anything you want).

To accomplish that, we will need the JavaScript method Object.keys().

  • Object.keys() method returns an array of a given object but only the own properties of the object

Let’s write the standard for loop:

var keys = Object.keys(obj)
for (var i = 0; i < keys.length; i++) {
    console.log(obj[keys[i]]);
}

Now we have a solution where we decreased the iteration time by eliminating the time for the evaluation `keys.length` from O(N) to O(1) which is a big time saving if we iterate big arrays.
So, during the development, if you are not limited (like applying some best practices,…), you can add another optimization, by using while loop.

var i = keys.length;
while (i--) {
    console.log(obj[keys[i]]);
}

In this case, we do not declare a new variable, we don’t execute new operations and the while loop will automatically stop when it reaches -1.

Speed testing:

Since the new browsers like Chrome are very fast and optimized, in order to see the best speed differences, I would suggest executing the loops on IE where you will be able to see a real speed difference between the loops.

var arr = new Array(10000);

Example speed test 1	
console.time();                        
for (var i = 0; i < arr.length; i++) {
    // operations...		
    var sum = i * i;   		
}
Execution 1: 4.4ms		
Execution 2: 5.5ms		
Execution 3: 5ms			
Execution 4: 4.6ms			
Execution 5: 5ms	
					
Example speed test 2                    
console.timeEnd(); 	          
while (i--) {
    // operations...
    var sum = i * i;
}
console.timeEnd();

Execution 1: 3.7ms
Execution 2: 4.8ms
Execution 3: 3.9ms
Execution 4: 3.8ms
Execution 5: 4.2ms

Thank you for reading and I would appreciate any feedback.

Making Swift networking code more readable

Reading Time: 3 minutes

With Swift 5 a new type got introduced:

@frozen public enum Result<Success, Failure> where Failure : Error {

    /// A success, storing a `Success` value.
    case success(Success)

    /// A failure, storing a `Failure` value.
    case failure(Failure)

The Result type is an enum consisting of 2 cases. The success and the failure case. Each of them can hold a generic value. The failure case, however, is limited to Types extending the Error type.

Not a big deal? Sure, but it’s the little things which add up and make a difference in the long run.

Lately, I was migrating from SwiftyJSON to native JSON parsing. Each network call was implemented in the following way:

func fetchSomething(completion: @escaping (SomeReturnValue?, SomeError?) -> Void) {
    NetworkingTool.request { (response) in
        guard response.isValid
            else { completion(nil, .somethingBad); return }
        do {
            let returnValue = try SomeReturnValue(response: response)
            completion(returnValue, nil)
        } catch {
            completion(nil, .scarry)
        }
    }
}

Looks okayish. Good. So let’s use it:

fetchSomething { (result, error) in
    guard error == nil
        else { handleError(error: error); return }
    doSomething(result: result)
}

Ok. But how to implement the doSomething? With an optional? This can’t be right, right? Force unwrap the result? And what about the error case? Force unwrap it? Oh and wait, what about the case where neither a result nor an error is returned? Is this even a thing? Ok, let me look up the implementation…

So a tiny bit of ambiguity paired with different people working on different parts of the network stack for different features can cause a real heterogeneous system. (Which does not imply that this is a bad system!)

If the company you’re working for is in favour of code ownership, you may not encounter this one. But so far no company I worked for was about code ownership. It’s usually your code is my code is our code, comrade. Period. There are simply too many trucks outside.

As long as code ownership isn’t a thing and you do not want to spend time on endless syntax and architectural discussions with little benefit or enforce a (new) best practice on all of your colleagues. Again. It comes really handy to have a built-in Result type which is reasonably unambiguous.

And since we all know that we’re spending more time reading code than writing, this saves us all valuable time.

Typescript/ES7 Decorators to make Vuex modules a breeze

Reading Time: 5 minutes

Overview

Who does not like to use Vuex in a VueJS App? I think no one 🙂

Today I would like to show you a very useful tool written in TypeScript that can boost your productivity with Vuex: vuex-module-decorators. Lately, it’s getting more popular. Below you can see the weekly downloads of the package which raise up constantly:

Weekly downloads on npmjs.com

But what does it exactly do and which benefit does it provide?

  • Typescript classes with strict type of safety
    Create modules where nothing can go wrong. The type check at compile time ensures that you cannot mutate data that is not part of the module or cannot access unavailable fields.
  • Decorators for declarative code
    Annotate your functions with @Action or @Mutation to automatically turn them into Vuex module methods.
  • Autocomplete for actions and mutations
    The shape of modules is fully typed, so you can access action and mutation functions with type-safety and get autocomplete help.

In short, with this library, you can write Vuex module in this format:

import { VuexModule, Module, Mutation, Action } from 'vuex-module-decorators'
import { get } from 'axios'

@Module
export default class Posts extends VuexModule {
    posts: PostEntity[] = [] // initialise empty for now

    get totalComments (): number {
        return posts.filter((post) => {
            // Take those posts that have comments
            return post.comments && post.comments.length
        }).reduce((sum, post) => {
            // Sum all the lengths of comments arrays
            return sum + post.comments.length
        }, 0)
    }

    @Mutation
    updatePosts(posts: PostEntity[]) {
        this.posts = posts
    }

    @Action({commit: 'updatePosts'})
    async function fetchPosts() {
        return get('https://jsonplaceholder.typicode.com/posts')
    }
}

As you can see, thanks to this package, we are able to write a Vuex module by writing a class which provides Mutations, Actions and Getters. Everything in one single file. How cool is that?

Benefits of type-safety

Instead of using the usual way to dispatch and commit…

store.commit('updatePosts', posts)
await store.dispatch('fetchPosts')

…with the getModule Accessor you can now use a more type-safe mechanism that does not offer type safety for the user data and no help for automatic completion in IDEs.

import { getModule } from 'vuex-module-decorators'
import Posts from `~/store/posts.js`

const postsModule = getModule(Posts)

// access posts
const posts = postsModule.posts

// use getters
const commentCount = postsModule.totalComments

// commit mutation
postsModule.updatePosts(newPostsArray)

// dispatch action
await postsModule.fetchPosts()

Core concepts

State

All properties of the class are converted into state props. For example, the following code

import { Module, VuexModule } from 'vuex-module-decorators'

@Module
export default class Vehicle extends VuexModule {
  wheels = 2
}

is equivalent to this:

export default {
  state: {
    wheels: 2
  }
}

Mutations

All functions decorated with @Mutation are converted into Vuex mutations. For example, the following code

import { Module, VuexModule, Mutation } from 'vuex-module-decorators'

@Module
export default class Vehicle extends VuexModule {
  wheels = 2

  @Mutation
  puncture(n: number) {
    this.wheels = this.wheels - n
  }
}

is equivalent to this:

export default {
  state: {
    wheels: 2
  },
  mutations: {
    puncture: (state, payload) => {
      state.wheels = state.wheels - payload
    }
  }
}

Actions

All functions that are decorated with @Action are converted into Vuex actions.

For example this code

import { Module, VuexModule, Mutation, Action } from 'vuex-module-decorators'
import { get } from 'request'

@Module
export default class Vehicle extends VuexModule {
  wheels = 2

  @Mutation
  addWheel(n: number) {
    this.wheels = this.wheels + n
  }

  @Action
  async fetchNewWheels(wheelStore: string) {
    const wheels = await get(wheelStore)
    this.context.commit('addWheel', wheels)
  }
}

is equivalent to this:

const request = require(‘request')

export default {
  state: {
    wheels: 2
  },
  mutations: {
    addWheel: (state, payload) => {
      state.wheels = state.wheels + payload
    }
  },
  actions: {
    fetchNewWheels: async (context, payload) => {
      const wheels = await request.get(payload)
      context.commit('addWheel', wheels)
    }
  }
}

Advanced concepts

Namespaced Modules

If you intend to use your module in a namespaced way, then you need to specify so in the @Module decorator:

@Module({ namespaced: true, name: 'mm' })
class MyModule extends VuexModule {
  wheels = 2

  @Mutation
  incrWheels(extra: number) {
    this.wheels += extra
  }

  get axles() {
    return this.wheels / 2
  }
}

const store = new Vuex.Store({
  modules: {
    mm: MyModule
  }
})

Registering global actions inside namespaced modules

In order to register actions of namespaced modules globally, you can add a parameter root: true to @Action and @MutationAction decorated methods:

@Module({ namespaced: true, name: 'mm' })
class MyModule extends VuexModule {
  wheels = 2

  @Mutation
  setWheels(wheels: number) {
    this.wheels = wheels
  }
  
  @Action({ root: true, commit: 'setWheels' })
  clear() {
    return 0
  }

  get axles() {
    return this.wheels / 2
  }
}

const store = new Vuex.Store({
  modules: {
    mm: MyModule
  }
})

This way the @Action clear of MyModule will be called by dispatching clear although being in the namespaced module mm. The same thing works for @MutationAction by just passing { root: true } to the decorator-options.

Dynamic Modules

Modules can be registered dynamically simply by passing a few properties into the @Module decorator, but an important part of the process is, we first create the store, and then pass the store to the module:

import store from '@/store'
import {Module, VuexModule} from 'vuex-module-decorators'

@Module({dynamic: true, store, name: 'mm'})
export default class MyModule extends VuexModule {
  /*
  Your module definition as usual
  */
}

Installation

The installation of the package is quite simple and does not require many steps:

Download the package

npm install vuex-module-decorators
# or
yarn add vuex-module-decorators

Vue configuration

// vue.config.js
module.exports = {
  // ... your other options
  transpileDependencies: [
    'vuex-module-decorators'
  ]
}

For more details, you can check the plugin’s official documentation.

Conclusion

I personally think this package can rump up your productivity because it embraces the “modularisation” pattern by making your app more scalable. Another big advantage is the fact you have “type-checking” thankfully to TypeScript. If you have a VueJS TypeScript Application, I strongly recommend you this package.

Starting with unit testing using Vue.js 2 and Jest

Reading Time: 4 minutes

As a FrontEnd developer, you may know a lot of FrontEnd technologies and frameworks but in time you need to upgrade yourself as a developer. A good skill to strengthen your knowledge is to learn unit testing.

Since I am working with Vue.js for several years, we are going to see some of the basics for testing Vue components using the Jest JavaScript testing framework.

To start, first, we need a Vue.js 2 project created via the Vue CLI. After that we need to add the Jest framework to the project:

# jest unit testing
vue add @vue/unit-jest

I’ll make a simple component that will increase a number on click of a button:

// testComponent.js
export default {
  template: `
    <div>
      <span class="count">{{ count }}</span>
      <button @click="increase">Increase</button>
    </div>
  `,

  data() {
    return {
      count: 0
    }
  },

  methods: {
    increase () {
      this.count++
    }
  }
}

The way of testing is by mounting the components in isolation, after that comes the mocking the needed inputs like injections, props and user events. In the end, comes the confirmation of the outputs of the rendered results emitted events etc.

After that, the components are returned inside a wrapper. A wrapper is an object that contains a mounted component or a VNode and methods to test them.

Let’s create a wrapper using the mount method:

// jestTest.js

// first we import the mount method
import { mount } from '@/vue/test-utils'
import Calculate from './calculate'

// then we mount (wrap) the component
const wrapper = mount(Calculate)

// this way you can access the Vue instance
const vm = wrapper.vm

// you can inspect the wrapper by logging it into the console
console.log(wrapper)

Next step after we do the wrapping, follows to verify if the rendered HTML output of the component matches the expectations.

import { mount } from '@vue/test-utils'
import Calculate from './calculate'

describe('Calculate', () => {
  // Now mount the component and you have the wrapper
  const wrapper = mount(Calculate)

  it('renders the correct markup', () => {
    expect(wrapper.html()).toContain('<span class="calculate">0</span>')
  })

  // it's also easy to check for the existence of elements
  it('has a button', () => {
    expect(wrapper.contains('button')).toBe(true)
  })
})

Then run the tests with npm test and see them pass.

The code in testComponent.js should increment the number on button click so next step is to simulate the user interaction. For this, we need the wrapper’s method wrapper.find() to get the wrapper for the button and then simulate the click event by calling the method trigger().

it('simulation of button click should increment the calculate by 2', () => {
  expect(wrapper.vm.calculate).toBe(0)
  const button = wrapper.find('button')
  button.trigger('click')
  button.trigger('click')
  expect(wrapper.vm.calculate).toBe(2)
})

For asynchronous updates, we use the Vue.nextTick()(need to receive a function as a parameter) method, which comes from Vue. With this method, we are waiting for the DOM update and after that, we execute the code (the code in the function parameter).

// this will not be caught

it('time out', done => {
  Vue.nextTick(() => {
    expect(true).toBe(false)
    done()
  })
})


// the three following tests will work as expected 
// (1)

it('catch the error using done method', done => {
  Vue.config.errorHandler = done
  Vue.nextTick(() => {
    expect(true).toBe(false)
    done()
  })
})

// (2)
it('catch the error using a promise', () => {
  return Vue.nextTick()
    .then(function() {
      expect(true).toBe(false)
    })
})

it('catch the error using async/await', async () => {
  await Vue.nextTick()
  expect(true).toBe(false)
})

Using nextTick can be tricky for the errors because the errors thrown inside it might not be caught by the test runner. That is happening as a consequence of using promises internally. To fix this we can set the done callback as a Vue’s global error handler (1) or we can use the nextTick method without parameter and return it as a promise (2) like we did earlier.

This article is a guide on how to set up the environment and start writing unit tests using Jest. For more information about testing with Vue and using Jest, you can visit the official site for Vue test utils.

Experiences of FrontendConnect 2019 conference Warsaw, Poland

Reading Time: 4 minutes

INTRODUCTION

Everybody has an open lifetime book full of blank pages, waiting to be filled. We write the story as we go, so back in November 2019, I have started the chapter ‘Frontend conferences’ by attending the FrontendConnect2019 in Warsaw, Poland, thanks to my company N47.

My motivation to choose this conference was the fact that I will gain new knowledge, and exchange practical ways of using frontend frameworks. Despite this, given the fact that there were great speakers from the IT world, I had no doubt choosing this tech event. Duration of the event was three days, one workshop day and two speaking conference days.

WHICH WORKSHOP DID I ATTEND TO?

As I was experienced with Vue.js, I wanted to upgrade the knowledge with Nuxt as their workshop description was “It may take it to the next level, thanks to its convention over configuration approach.” I got a certificate of attendance and completion of “My first Nuxt.js application” by the Vue.js Core Team member Darek ‘Gusto’ Wędrychowski. Coding under the eye of ‘Gusto’ and having a wonderful panorama view of Warsaw in my horizon, was definitely a day well spent.

WHICH PRESENTATION DID I ATTEND TO?

Rich agenda with scheduled talks, thoughts about which ones to choose, moreover similar questions were going through my mind. I attended the ones that caught my eye and were mostly within my interests.

At the beginning of each day, there was a high valued speaker opening the day with their talks. The first day I had to meet and listen to the very appreciated, Douglas Crockford with his JSON Saga.

The second day, there was Minko Gechev, a Google engineer working on the Angular framework with the talk ‘The Future of Front-End Frameworks’.

Some other topics that I attended to were about the state management in a world of hooks, some optimizations of the modern JavaScript applications and loading them instantly, as well as Angular and Vue.js 3.0 topics.

WHAT CAUGHT MY MIND?

Two of my favourite talks were ‘The JSON Saga’ – Douglas Crockford and ‘Vue 3.0 for Library Authors’ – Damian Dulisz.

The JSON Saga

Douglas was retelling the story about how he discovered JSON (JavaScript Object Notation). He explained how he did not invent, but found it in the early 2000s, named it and described its usefulness. JSON is a format for storing data and establishing communication between the servers. He explained how some companies complained and did not want to accept JSON because they were used to XML, and could not consider anything else, at that moment. He mentioned that some of the people denied its usage because of it not being a standard. So, what he did next was buying JSON.org, a website which after a few years spread among the users. After a while, JSON got the support of all languages. He announced that there will be no more changes to JSON because for him there is no feature more important than the stability of JSON.

Vue 3.0 for Library Authors

Getting more in details about this topic and Vue 3.0-alpha version will be covered in my next blog.

THE CULTURE AND ENVIRONMENT IN THE CONFERENCE

Frontend Connect was happening in the theatre of the Palace of Culture and Science in Warsaw, Poland where the history and modern world meet at the same time. It is one of the symbolic icons of Warsaw and the place of the city`s rebirth. There were people from all over the world, and the atmosphere was really friendly. Everybody was discussing the topics and shared their work ethics.

CONCLUSION

Visiting conferences is a really good way to meet new friendly people that you have a lot in common with, as well as having an opportunity to reach out to the speaker if you enjoyed the talk, and discuss what you found interesting. We should always strive for more experiences like this and face new challenges within modern technologies. With that being said, we need to nurture our idea to reach our full potential, in order to make a bigger impact in the IT world.