1

I am looking at using the Stepper component from Angular Material in my application, where I need to support IE 11.

If I browse to the documentation page using IE, the examples all run fine, so it does appear it will work in IE.

So I created a new Angular project, and used ng add @angular/material to add Material.

I followed the rest of the steps as per these instructions

I have the following packages

        {
      "name": "mat-stepper1",
      "version": "0.0.0",
      "scripts": {
        "ng": "ng",
        "start": "ng serve",
        "build": "ng build",
        "test": "ng test",
        "lint": "ng lint",
        "e2e": "ng e2e"
      },
      "private": true,
      "dependencies": {
        "@angular/animations": "~7.2.0",
        "@angular/cdk": "~7.3.7",
        "@angular/common": "~7.2.0",
        "@angular/compiler": "~7.2.0",
        "@angular/core": "~7.2.0",
        "@angular/forms": "~7.2.0",
        "@angular/material": "^7.3.7",
        "@angular/platform-browser": "~7.2.0",
        "@angular/platform-browser-dynamic": "~7.2.0",
        "@angular/router": "~7.2.0",
        "core-js": "^2.5.4",
        "rxjs": "~6.3.3",
        "tslib": "^1.9.0",
        "zone.js": "~0.8.26"
      },
      "devDependencies": {
        "@angular-devkit/build-angular": "~0.13.0",
        "@angular/cli": "~7.3.8",
        "@angular/compiler-cli": "~7.2.0",
        "@angular/language-service": "~7.2.0",
        "@types/node": "~8.9.4",
        "@types/jasmine": "~2.8.8",
        "@types/jasminewd2": "~2.0.3",
        "codelyzer": "~4.5.0",
        "jasmine-core": "~2.99.1",
        "jasmine-spec-reporter": "~4.2.1",
        "karma": "~4.0.0",
        "karma-chrome-launcher": "~2.2.0",
        "karma-coverage-istanbul-reporter": "~2.0.1",
        "karma-jasmine": "~1.1.2",
        "karma-jasmine-html-reporter": "^0.2.2",
        "protractor": "~5.4.0",
        "ts-node": "~7.0.0",
        "tslint": "~5.11.0",
        "typescript": "~3.2.2"
      }
    }

Ny JS target in tsconfig.json is "target": "es5",

My app modules is as follows...

        import { BrowserModule } from '@angular/platform-browser';
    import { NgModule } from '@angular/core';

    import { AppComponent } from './app.component';
    import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
    import { WizardStepperComponent } from './wizard-stepper/wizard-stepper.component';
    import { MatStepperModule, MatInputModule, MatButtonModule, MatAutocompleteModule } from '@angular/material';

    @NgModule({
      declarations: [
        AppComponent,
        WizardStepperComponent
      ],
      imports: [
        BrowserModule,
        BrowserAnimationsModule,
        MatStepperModule,
        MatInputModule,
        MatButtonModule,
        MatAutocompleteModule
      ],
      providers: [],
      bootstrap: [AppComponent]
    })
    export class AppModule { }

Finally, I created a component with the following..

<mat-horizontal-stepper #stepper>
      <mat-step>
        Step 1
      </mat-step>
      <mat-step>
        Step 2
      </mat-step>
      <mat-step>
        Step 3
      </mat-step>
      <!-- one option -->

    </mat-horizontal-stepper>

    <!-- second option -->
    <div>
      <button (click)="goBack(stepper)" type="button" [disabled]="stepper.selectedIndex === 0">Back</button>
      <button (click)="goForward(stepper)" type="button"
        [disabled]="stepper.selectedIndex === stepper._steps.length-1">Next</button>

      <!-- using totalStepsCount -->
      <!-- <button (click)="goForward(stepper)" type="button" [disabled]="stepper.selectedIndex === totalStepsCount-1">Next</button> -->
    </div>

        import { Component, OnInit, ViewChild } from '@angular/core';
    import { MatStepper } from '@angular/material';

    @Component({
      selector: 'app-wizard-stepper',
      templateUrl: './wizard-stepper.component.html',
      styleUrls: ['./wizard-stepper.component.scss']
    })
    export class WizardStepperComponent implements OnInit {

      @ViewChild('stepper') private myStepper: MatStepper;
      totalStepsCount: number;

      constructor() { }

      public ngOnInit() : void {
      }

      public ngAfterViewInit() : void {
        this.totalStepsCount = this.myStepper._steps.length;
      }

      public goBack(stepper: MatStepper) : void {
        stepper.previous();
      }
      public  goForward(stepper: MatStepper) : void {
        stepper.selectedIndex = 2;
      }
    }

All runs fine in Chrome, Edge, Firefox, but when I try in in IE, I get the following error....

        Unhandled Promise rejection: 'customElements' is undefined ; Zone: <root> ; Task: Promise.then ; Value: ReferenceError: 'customElements' is undefined ReferenceError: 'customElements' is undefined
       at AppComponent (http://localhost:4200/main.js:85:9)
       at createClass (http://localhost:4200/vendor.js:63022:13)
       at createDirectiveInstance (http://localhost:4200/vendor.js:62899:5)
       at createViewNodes (http://localhost:4200/vendor.js:71259:21)
       at createRootView (http://localhost:4200/vendor.js:71173:5)
       at callWithDebugContext (http://localhost:4200/vendor.js:72181:9)
       at debugCreateRootView (http://localhost:4200/vendor.js:71691:5)
       at ComponentFactory_.prototype.create (http://localhost:4200/vendor.js:62378:9)
       at ComponentFactoryBoundToModule.prototype.create (http://localhost:4200/vendor.js:60100:9)
       at ApplicationRef.prototype.bootstrap (http://localhost:4200/vendor.js:68946:9)
       "Unhandled Promise rejection:"
       "'customElements' is undefined"
       "; Zone:"
       "<root>"
       "; Task:"
       "Promise.then"
       "; Value:"
       {
          [functions]: ,
          __proto__: { },
          description: "'customElements' is undefined",
          message: "'customElements' is undefined",
          name: "ReferenceError",
          ngDebugContext: { },
          number: -2146823279,
          stack: "ReferenceError: 'customElements' is undefined
       at AppComponent (http://localhost:4200/main.js:85:9)
       at createClass (http://localhost:4200/vendor.js:63022:13)
       at createDirectiveInstance (http://localhost:4200/vendor.js:62899:5)
       at createViewNodes (http://localhost:4200/vendor.js:71259:21)
       at createRootView (http://localhost:4200/vendor.js:71173:5)
       at callWithDebugContext (http://localhost:4200/vendor.js:72181:9)
       at debugCreateRootView (http://localhost:4200/vendor.js:71691:5)
       at ComponentFactory_.prototype.create (http://localhost:4200/vendor.js:62378:9)
       at ComponentFactoryBoundToModule.prototype.create (http://localhost:4200/vendor.js:60100:9)
       at ApplicationRef.prototype.bootstrap (http://localhost:4200/vendor.js:68946:9)",
          Symbol()_g.y4outqxtpgv: undefined,
          Symbol(rxSubscriber)_h.y4outqxtpgv: undefined
       }
       "ReferenceError: 'customElements' is undefined
       at AppComponent (http://localhost:4200/main.js:85:9)
       at createClass (http://localhost:4200/vendor.js:63022:13)
       at createDirectiveInstance (http://localhost:4200/vendor.js:62899:5)
       at createViewNodes (http://localhost:4200/vendor.js:71259:21)
       at createRootView (http://localhost:4200/vendor.js:71173:5)
       at callWithDebugContext (http://localhost:4200/vendor.js:72181:9)
       at debugCreateRootView (http://localhost:4200/vendor.js:71691:5)
       at ComponentFactory_.prototype.create (http://localhost:4200/vendor.js:62378:9)
       at ComponentFactoryBoundToModule.prototype.create (http://localhost:4200/vendor.js:60100:9)
       at ApplicationRef.prototype.bootstrap (http://localhost:4200/vendor.js:68946:9)"

At this stage I have added no extra polyfills, and not uncommented anything from polyfills.ts

Any ideas how I can get this to work in IE?

Going to the Sample code I cannot see anything extra as to how they get it to work on the doco page.

Update

My polyfills.ts has the following

        /**
     * This file includes polyfills needed by Angular and is loaded before the app.
     * You can add your own extra polyfills to this file.
     *
     * This file is divided into 2 sections:
     *   1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
     *   2. Application imports. Files imported after ZoneJS that should be loaded before your main
     *      file.
     *
     * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
     * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
     * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
     *
     * Learn more in https://angular.io/guide/browser-support
     */

    /***************************************************************************************************
     * BROWSER POLYFILLS
     */

    /** IE10 and IE11 requires the following for NgClass support on SVG elements */
    // import 'classlist.js';  // Run `npm install --save classlist.js`.

    /**
     * Web Animations `@angular/platform-browser/animations`
     * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
     * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
     */
    // import 'web-animations-js';  // Run `npm install --save web-animations-js`.

    /**
     * By default, zone.js will patch all possible macroTask and DomEvents
     * user can disable parts of macroTask/DomEvents patch by setting following flags
     * because those flags need to be set before `zone.js` being loaded, and webpack
     * will put import in the top of bundle, so user need to create a separate file
     * in this directory (for example: zone-flags.ts), and put the following flags
     * into that file, and then add the following code before importing zone.js.
     * import './zone-flags.ts';
     *
     * The flags allowed in zone-flags.ts are listed here.
     *
     * The following flags will work for all browsers.
     *
     * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
     * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
     * (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
     *
     *  in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
     *  with the following flag, it will bypass `zone.js` patch for IE/Edge
     *
     *  (window as any).__Zone_enable_cross_context_check = true;
     *
     */

    /***************************************************************************************************
     * Zone JS is required by default for Angular itself.
     */
    import 'zone.js/dist/zone';  // Included with Angular CLI.


    /***************************************************************************************************
     * APPLICATION IMPORTS
     */
halfer
  • 19,824
  • 17
  • 99
  • 186
peterc
  • 6,921
  • 9
  • 65
  • 131
  • Did you do this ?https://stackoverflow.com/questions/35140718/angular-2-4-5-not-working-in-ie11/42426495#42426495 – Zze Aug 29 '19 at 01:13
  • I've added the contents of my polyfills.ts as UPDATE1, so I don't have any of the `import 'core-js` suggested in there. Am am already targeting `es5`. Most answers are for earlier Angular versions (I have 7 here). Do I still manually add these imports? – peterc Aug 29 '19 at 01:21
  • 2
    Oh, I thought what the heck and did include the `import 'classlist.js` and `import 'web-animations-js` even thought I thought not relevant here, and now it works!! – peterc Aug 29 '19 at 01:25

1 Answers1

1

The solution here was to just install and uncomment the following in polyfills.ts..

import 'classlist.js';  // Run `npm install --save classlist.js`.
import 'web-animations-js';  // Run `npm install --save web-animations-js`.

I did not think they were relevant here, but once I included the, the stepper now works in IE! In future I won't guess and just do.

peterc
  • 6,921
  • 9
  • 65
  • 131