How do support Internet Explorer in Angular 8

How do support Internet Explorer in Angular 8

Waiting for the new Edge with Chromium, let’s try to understand how to support Internet Explorer in Angular 8

For some strange reason, the world has not yet forgotten Internet Explorer. If you’re a front-end developer, this is a very stressful truth, especially if Angular is your favorite front-end framework.

As you probably know, Angular supports Internet Explorer until version 9, but you need to use some “polyfill” scripts. If you use the CLI, and I hope that you are not starting projects without CLI still, you already have a polyfills.ts in your src folder. This file contains some mandatory polyfills like “zone.js”, and some optional imports, commented by default, based on the needs of your project.

In the latest Angular major release (8.x.x), the team introduced a new feature named “differential loading”, that creates two packages when you build your project: one for the modern browser using the ES2015 syntax with no need of polyfills, and one, larger than the first, that contains polyfills and uses the ES5 syntax to support old browsers.

This is image title

How does this feature work? How the browser chooses the correct bundle? It is simpler than you think: the index.html points all the files and uses the attributes nomodule and type=”module” to understand if the browser support ES modules. All modern browsers only download the scripts with the attribute type=”module”. Legacy browsers, instead, do not know this attribute and download files with nomodule attributes. Actually, some old browsers download all the files, but they only execute the correct ones.

This is image title

This feature works fine with the build command, but with the serve, test and e2e commands, only the es2015 bundles are created. So, if we execute the classic ng serve command to test our application in development mode, we can’t test it with Internet Explorer. We can solve this problem changing our tsconfig.json “target” property to “es5” instead of “es2015”, but if we want to maintain both the configurations we can add a “tsconfig-es5.app.json” in our root folder with this configuration:

{
 "extends": "./tsconfig.app.json",
 "compilerOptions": {
   "target": "es5"
 }
}

Now we can use the angular.json to add a new configuration to our project. In the “build” and “serve” sections, we need to add a new “es5” configuration, to specify the new tsconfig created, and the use of it in the “serve” command:

"build": {
    "builder": "@angular-devkit/build-angular:browser",
    "options": { ...
    },
    "configurations": {
        "production": { ...
        },
        "es5": {
            "tsConfig": "./tsconfig-es5.app.json"
        }
    }
},
"serve": {
    "builder": "@angular-devkit/build-angular:dev-server",
    "options": { ...
    },
    "configurations": {
        "production": { ...
        },
        "es5": {
            "browserTarget": "IEdemo:build:es5"
        }
    }
}

We can then run our project in development mode with the command:

ng serve --configuration es5

Is the problem solved therefore? Do we need anything else? It would be wonderful but it’s not so. We still need to test our application on Internet Explorer. If we are on a Windows platform, we can start Internet Explorer and test our application, whereas if we are on a Mac and we have a Parallels license, we can follow the instructions of one of articles Debugging Angular in Windows with Parallels and run the server on Mac, testing the application on a virtualized instance of Windows.

Using the Explorer emulation feature, we can test any old version of the browser:

This is image title

Let’s take an example. Usually, it can be convenient to use the attribute hidden instead of *ngIf to hide a piece of HTML, both for functional and for performance reasons. If we want to use a button to show or to hide a DIV element with the hidden attribute, we can write this simple code:

<button (click)="elementVisible = !elementVisible">
 Show/hide
</button>
<div [hidden]="elementVisible">
 <h1>
   Welcome to {{ title }}!
 </h1>
</div>

It works without problems with any modern browser and in IE11, but it doesn't on IE10.

This is image title

We need an additional polyfill to add the hidden functionality to IE10, but, to implement it, we need to understand why hidden doesn’t work. If we apply manually the hidden attribute to the HTML element, the piece of the UI hides correctly. The problem is not the attribute hidden, but the Angular binding that doesn’t add the attribute if it doesn't exist for the element. So, we need to add “hidden” attribute to the HTMLElement of the browser if it doesn’t exist, placing, for example, this code in an hidden-attribute-polyfill.ts and importing it in the main polyfills.ts:

((global: any) => {
 'use strict';

 const notInBrowser = !global.HTMLElement || !HTMLElement.prototype;
 const alreadyDefined = 'hidden' in HTMLElement.prototype;
 const notPossibleToImplement = typeof Object.defineProperty === 'undefined';

 if (notInBrowser || alreadyDefined || notPossibleToImplement) {
   return;
 }

 Object.defineProperty(HTMLElement.prototype, 'hidden', {
   get() {
     return this.hasAttribute('hidden');
   },
   set(value) {
     if (value) {
       this.setAttribute('hidden', '');
     } else {
       this.removeAttribute('hidden');
     }

     return value;
   },
 });
})(typeof window === 'undefined' ? this : window);

Now it works:

This is image title

You can find the sample code here

Happy coding and thank for reading !

Originally published on blexin.com

angular angular-js web-development

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

Hire Web Developer

Looking for an attractive & user-friendly web developer? HourlyDeveloper.io, a leading web, and mobile app development company, offers web developers for hire through flexible engagement models. You can **[Hire Web...

Hire Node.JS Developers | Skenix Infotech

We are providing robust Node.JS Development Services with expert Node.js Developers. Get affordable Node.JS Web Development services from Skenix Infotech.

Important reasons for developers to adopt Angular JS development

In the current scenarios, e-commerce companies are very keen to create an online impact. The web and app development market are at its peak of popularity. There is a high demand for web and app developers with a growing number of websites. Angular...

Why Web Development is Important for your Business

With the rapid development in technology, the old ways to do business have changed completely. A lot more advanced and developed ways are ...