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.

JHipster with Google App Engine and Cloud MySQL

Reading Time: 5 minutes

How does it sound to set up a complete spring application, with front-end and database? With all the models, repositories and controllers? Even with Unit and Integration tests, with mocked data? All within a few hours? Your solution is JHipster!

JHipster

JHipster or “Java Hipster” is a handy application generator, a development platform, to develop and deploy web applications. JHipster has become popular in a short time, and it has been featured in many conferences all around the globe – Montreal, Omaha, Taipei, Richmond, Frankfurt, Paris, London. It supports:

  • Spring Boot (Back-end)
  • Angular/React/Vue (Front-end)
  • Spring microservices

JHipster is used for generating complete applications, it will create for you a Spring Boot and Angular/React/Vue application, high-quality application with most of the things pre-configured, using Java as back-end technology and an extensive set of Spring technologies: Spring Security, Spring Boot, Spring MVC (providing a framework for web-sockets, REST and MVC), Spring Data, etc. and Angular/React/Vue front-end and a suite of pre-configured development tools like Yeoman, Maven, Gradle, Grunt, Gulp.js and Bower.

JHipster gives you a head start in creating Spring Boot application with a set of pre-defined screens for user management, monitoring, and logging. The generated Spring Boot application is specifically tailored to make working with Angular/React/Vue a smoother experience. At the top of all that, JHipster also gives you the tools to update, manage and package the resulting application.

By now you may think it sounds too good to be true… But it is not everything that JHipster offers. If you are a web developer, by now probably you have a lot of questions. 🙂
One important question we will answer in this blog post: is it supported by today’s cloud solutions, is it compatible with all of them? The answer is yes, it is compatible with the popular cloud solutions from Google, Amazon, Microsoft, and Heroku. Let’s see what it takes to make a complete integration in Google’s cloud platform, the app engine.

Compatibility Test - NEXCOM

Google App Engine

Google App Engine is a cloud solution provided by Google, a platform for developing and hosting web applications in data centres managed by Google; Platform as a Service (PaaS). Applications are sandboxed and run across multiple servers. The App Engine supports Java or Python, uses the Google query language and stores data in Google BigTable.

It is free of usage up to a certain amount of resource usage. After the user is exceeding the limited usage rates for storage, CPU resources, requests or number of API calls and concurrent requests can pay for more of these resources.

It is fully compatible with the JHipster generated projects. What it takes to host your application is just to follow the official how-to guide from Google App Engine documentation, as normal Spring Boot Application. To make things easier, Google offers a database which works closely with the Google App Engine, the Cloud SQL.

Cloud SQL

Cloud SQL is a database service offered by Google for their cloud solutions, fully-managed that makes it easy to configure, manage, maintain, and operate your relational databases on Google Cloud Platform.

It offers three database options to integrate with:

  • MySQL
  • PostgreSQL
  • SQL Server

Let’s get into details of integrating with Cloud SQL for MySQL:

  1. The first step is to create a Cloud SQL instance on the Google Cloud Platform, which requires few things like instance ID, password and etc. to be set and it gives you the option to choose the MySQL database version.
  2. The following step is to create the database in the newly created instance. It is possible to have more databases in one instance.
  3. Now, our application, in the case to be able to communicate with the Cloud SQL, without any permission blockers, we need to register the application in the Cloud SQL and manually configure the service account roles.
  4. The final step is connecting your application to the created Cloud SQL instance. It is done through JDBC. All the required properties can be found in the overview of the Cloud SQL, instance connection name, credentials and etc.

So the conclusion: don’t be afraid to invest some time in new technologies, be curious, you never know where they may lead you. Thank you for reading. 🙂

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.

Webpack: The Good, The Bad and The Ugly

Reading Time: 5 minutes

Introduction

Webpack, a static module bundler, a complex yet simple tool, that allows you to spend between 10 minutes and 10 hours to make a simple web application bundlable.

The Good

As a static module bundler, Webpack delivers a bundle of code that’s easily parseable for your browser or node environment. It allows users to use the UMD/AMD system of bundling code and applies it on images, HTML, CSS and much much more. This allows the developer to create a module or more modules with a segment or multiple segments of a web app, and serve it all, or serve parts.
One of the major sell points of Webpack is the ability to modify it to your choosing. It’s a rich ecosystem of plugins that exist to enhance the already plentiful options of the bundler itself. This allows for Front-end libraries and frameworks to use it to bundle their code using custom solutions and plugins, the likes of Angular, ReactJS and VueJS.

This is made easy by the years of development through which we have reached Webpack 4, that allows for multiple configuration files for development and production environments.

The example in the image is a view into the differences that allow for good development overview and testing, yet at the same time make it possible to use a single script to build a production-ready build. All of this together makes Webpack a viable bundler for most JS projects, especially when it’s the base of ecosystems like in Angular or React.

The Bad

Whilst Webpack is a good bundler of JS, it’s not the only one available. Issues in Webpack come from the fact that most of the libraries that you use need to have been worked on and developed with Webpack bundling in mind. Its native module support is limited, requiring you to specify those resources and what way you do want them to be represented in the final build. And most of the time, a random version update of a model can break the entire project, even on tertiary modules.

The learning curve of Webpack is getting higher and higher, it all depends on how complex a project you are working on, and whether you are working with a preconfigured project or building a configuration on your own.

Just for this article I have gone over not only the Webpack docs, but around 20 articles, a ton of github issues. And around a year and a half of my personal setup experience bundling project with Webpack using Three.js, A-Frame, React, Angular, and a myriad of other niche applications. And in the end it still feel like i’ve barely scratched the surface.

The entire debugging process is ugly, it depends upon source-maps which vary from library to library. You can use the in-built Webpack option or use a plugin for your specific tech, it will never be fun. Loading up a 160k code bundle and blocking your pc, even with source-maps.

The Ugly

All in all, when you give Webpack a chance, your encounter will rarely be a pleasant one. There shall never be a valid standardized version for using and implementing the core. And the plugins don’t help. Each time you find something that works, something new will magically brake. It’s like trying to fix a sinking ship.

This image represents my average day using Webpack, if my project was the dog and Webpack the firestarter. Currently using it in combination with VueJS. It’s the same story, either use the vuecli and a preloaded config. Or regret not doing that later when you need to optimize your specific code integration that needs to run as a bundled part of a larger application.

The worst part of all of this probably is the widespread usage of black-box software like Webpack, which in theory is open source but is a bundle of libraries and custom code that takes as much time as a doctors thesis to study properly. And for all of this, it still is one of the better options out there.

Conclusion

Webpack as a bundler is excellent for use in a multitude of applications. Especially if someone else handles the config for you (Angular, React, Vue clis). It will hopefully become better, but like anything else in JS its roots and backwards compatibility will always bring it down. Be ready for a high learning curve and a lot of frustration. If you like to explore new things, or reimplement existing solutions, or optimize workflow, give it a try.