Using Angular 6

Table of Contents

Angular and The Secret Life(cycle) of Components

  • Angular 6 Setup

    Verify Node.js and Npm Install

    C:\Users\Helmut\AppData\Roaming\npm\node_modules>  node -v 
    v8.11.3
    
    C:\Users\Helmut\AppData\Roaming\npm\node_modules>  npm -v 
    5.6.0
    

    Install Angular Cli

    C:\Users\Helmut\AppData\Roaming\npm\node_modules>   npm install -g @angular/cli 
    C:\Users\Helmut\AppData\Roaming\npm\ng -> C:\Users\Helmut\AppData\Roaming\npm\node_modules\@angular\cli\bin\ng
    
    > @angular/cli@6.0.8 postinstall C:\Users\Helmut\AppData\Roaming\npm\node_modules\@angular\cli
    > node ./bin/ng-update-message.js
    
    npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.4 (node_modules\@angular\cli\node_modules\fsevents):
    npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.4: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
    
    + @angular/cli@6.0.8
    added 246 packages in 13.439s
    
    Ingore above warning: See
    https://github.com/npm/npm/issues/20639
    

    Verify Angular CLI

    C:\Users\Helmut\AppData\Roaming\npm\node_modules>   ng -v 
                        _                 ____ _     ___
        / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
       / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
      / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
     /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                    |___/
    
    
    Angular CLI: 6.0.8
    Node: 8.11.3
    OS: win32 x64
    Angular:
    ...
    
    Package                      Version
    ------------------------------------------------------
    @angular-devkit/architect    0.6.8
    @angular-devkit/core         0.6.8
    @angular-devkit/schematics   0.6.8
    @schematics/angular          0.6.8
    @schematics/update           0.6.8
    rxjs                         6.2.1
    typescript                   2.7.2
    

    Reference

    Create First Angular Project

    Prepare Project Structure

    D:\angular>    ng new FirstAngularPoject 
    
    CREATE FirstAngularPoject/angular.json (3656 bytes)
    CREATE FirstAngularPoject/package.json (1324 bytes)
    CREATE FirstAngularPoject/README.md (1035 bytes)
    CREATE FirstAngularPoject/tsconfig.json (384 bytes)
    CREATE FirstAngularPoject/tslint.json (2805 bytes)
    CREATE FirstAngularPoject/.editorconfig (245 bytes)
    CREATE FirstAngularPoject/.gitignore (503 bytes)
    CREATE FirstAngularPoject/src/environments/environment.prod.ts (51 bytes)
    CREATE FirstAngularPoject/src/environments/environment.ts (631 bytes)
    CREATE FirstAngularPoject/src/favicon.ico (5430 bytes)
    CREATE FirstAngularPoject/src/index.html (305 bytes)
    CREATE FirstAngularPoject/src/main.ts (370 bytes)
    CREATE FirstAngularPoject/src/polyfills.ts (3194 bytes)
    CREATE FirstAngularPoject/src/test.ts (642 bytes)
    CREATE FirstAngularPoject/src/assets/.gitkeep (0 bytes)
    CREATE FirstAngularPoject/src/styles.css (80 bytes)
    CREATE FirstAngularPoject/src/browserslist (375 bytes)
    CREATE FirstAngularPoject/src/karma.conf.js (964 bytes)
    CREATE FirstAngularPoject/src/tsconfig.app.json (194 bytes)
    CREATE FirstAngularPoject/src/tsconfig.spec.json (282 bytes)
    CREATE FirstAngularPoject/src/tslint.json (314 bytes)
    CREATE FirstAngularPoject/src/app/app.module.ts (314 bytes)
    CREATE FirstAngularPoject/src/app/app.component.html (1141 bytes)
    CREATE FirstAngularPoject/src/app/app.component.spec.ts (1001 bytes)
    CREATE FirstAngularPoject/src/app/app.component.ts (207 bytes)
    CREATE FirstAngularPoject/src/app/app.component.css (0 bytes)
    CREATE FirstAngularPoject/e2e/protractor.conf.js (752 bytes)
    CREATE FirstAngularPoject/e2e/src/app.e2e-spec.ts (314 bytes)
    CREATE FirstAngularPoject/e2e/src/app.po.ts (208 bytes)
    CREATE FirstAngularPoject/e2e/tsconfig.e2e.json (213 bytes)
    npm WARN deprecated istanbul-lib-hook@1.2.1: 1.2.0 should have been a major version bump
    npm WARN notice [SECURITY] ws has the following vulnerability: 1    
    ...
    

    Start Web Server and Run this project FirstAngularPoject

    D:\angular\FirstAngularPoject>   ng serve 
    ** Angular Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/ **
    
    Date: 2018-06-29T07:21:10.097Z
    Hash: e8e3505bb172de5054c9
    Time: 5298ms
    chunk {main} main.js, main.js.map (main) 10.7 kB [initial] [rendered]
    chunk {polyfills} polyfills.js, polyfills.js.map (polyfills) 227 kB [initial] [rendered]
    chunk {runtime} runtime.js, runtime.js.map (runtime) 5.22 kB [entry] [rendered]
    chunk {styles} styles.js, styles.js.map (styles) 15.6 kB [initial] [rendered]
    chunk {vendor} vendor.js, vendor.js.map (vendor) 3.07 MB [initial] [rendered]
    i 「wdm」: Compiled successfully.
    
    

    Access the first Angular App via Webbrowser

    URL: http://localhost:4200
    Image angular_img1.jpg  NOT Found

    https://material.angularjs.org/1.0.5/layout/container

    Webstorm Angular Poductivity Hints

    Create First Angular Project

    There are two ways to make a service a singleton in Angular:

    • Declare that the service should be provided in the application root.
    • Include the service in the AppModule or in a module that is only imported by the AppModule.
    • Reference Angular Singleton Services

    Sample:

    @Injectable({
      providedIn: 'root',
    })
    
    export class myServices implements OnInit {
       ...
    

    Apply complex Styles by calling a Component Function

    
    Component HTML Code:: [ngStyle]="calculateStyles(semester.semester)"
    
    <div class="content">
    
        <div class="card"  *ngFor="let semester of getSemester();  " >
          <div  [attr.id]="'semester' + semester.semester"
            [ngStyle]="calculateStyles(semester.semester)"
            class=" calc-study-div-height d-flex progress-div">
            <div  class="p-2 mr-auto progress-div">{{semester.semester}}  <br/> <p><span style="font-size: 14px">Sem</span> </p></div>
              <div class="p-2 progress-div"  *ngIf="(semester.semester  === 1); then thenBlock else elseBlock"></div>
              <ng-template #thenBlock>
                <p class="p-2 progress-div" style="text-align: right;" >
    
    
    Typescript Code
    
     calculateStyles(semId) {
        const style1 = {'background': ''};
        const style2 = {'background':  AppComponent.mainColor };
        const style3 = {'background-image': 'linear-gradient(-90deg, #0046A0, #009FD2)'};
        if (semId === this.currentSemesterId) {
          return style2;
        } else {
          if ((semId !== null) && (this.dataService.getSemEctsById(semId)) > 0) {
            return style3;
          } else {
            return style1;
          }
        }
      }
    

    Angular Difference between Constructor an NgOninit

    Import Modules

    • Import Http Module to an existing project
    • File: app.module.ts
    • 
      import { BrowserModule } from '@angular/platform-browser';
      import { NgModule } from '@angular/core';
      import { HttpClientModule } from '@angular/common/http';
      import { AppComponent } from './app.component';
      @NgModule({
        declarations: [
          AppComponent
        ],
        imports: [
          BrowserModule,
          HttpClientModule
        ],
        providers: [],
        bootstrap: [AppComponent]
      })
      export class AppModule { }
      

      Passing query paramters to a router link

      The triggering Code

      import { Component, OnInit } from '@angular/core';
      import {DataService} from '../services/data-service.service';
      import {Router} from '@angular/router';
      
      ...
      
      export class StudyProgressComponent implements OnInit {
      
        constructor(private dataService: DataService,
                    private router: Router) { }
      ...
      
        gotoSemester(semesterId: number) {
          console.log('_____ Goto Semester : ' + semesterId);
              this.router.navigate(['current'], { queryParams: { semester: semesterId} });
        }
      
      

      The receiving side waiting in an Observable

      import {Component, Input, OnInit} from '@angular/core';
      import {ActivatedRoute, Router} from '@angular/router';
      import {Subscription} from 'rxjs';
      
      export class SemesterHeaderComponent implements OnInit {
        ...
        constructor( private route: ActivatedRoute,
                     private router: Router) { }
      
        ngOnInit() {
          this.activeRouteSubscription = this.route
            .queryParams
            .subscribe(params => {
              /*
                 Defaults to 1.st Semester if no query param provided.
                 +params converts  the data from params array to number - no further type checking needed
              */
              this.currentSemesterId = +params['semester'] || -1;
              if ( this.currentSemesterId === -1) {
                console.log('_____________________ SemesterHeaderComponent:: Warning Semester not found in Query Params ! ');
                this.currentSemesterId = 1;
              }
              console.log('___ Updating Headline with SemesterId: ', this.currentSemesterId);
              this.setHeadline( this.currentSemesterId + '.Semester');
            });
        }
      
      

      Reference about routes

      External Links

      • Angular 2 Router can’t redirect externally. This doesn’t make sense, as an external resource can’t actually be a state of the app
      • Angular 2 offers the client-side Component Router for single page apps. Always redirecting to a component is consistent

      Reference

      Access-Control-Allow-Origin: Dealing with CORS Errors in Angular

      Browser shows following Eror

      Failed to load http://localhost:8080/api/auth/test: No 'Access-Control-Allow-Origin' header is present on the requested resource. 
      Origin 'http://localhost:4200' is therefore not allowed access.
      

      Potential Pitfalls running inta Access-Control-Allow-Origin problem

      Ajax Request Sample
      Hitting a server from a locally-served file file:///YourApp/index.html —— http://api.awesome.com
      Hitting an external API http://yourapp.com —— http://api.awesome.com
      Hitting an internal API http://yourapp.com —— http://api.yourapp.com
      Hitting a different port on the same host http://localhost:3000 —— http://localhost:4000
      Requesting over http from https or vice-versa https://yourapp.com —— https://yourapp.com

      Fix 1: Dev-Only: Disable Same Origin inside the browser

      • Using Chrom 32-bit Broser on Windows 10
      "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --disable-web-security --user-data-dir="C:/ChromeDevSession"
      

      Fix 2: Using a Proxy Server

      • Using Chrom 32-bit Broser on Windows 10

      Create a File proxy.json in your Project Top level Directory

      D:\dev\myProjects\dobby-the-companion_TDB> type proxy.json
      {
        "/api": {
          "target": "http://localhost:8080",
          "secure": false
        }
      }
      

      In file package.json add flag –proxy-config proxy.json to ng server

      {
        "name": "dobby-the-companion",
        "version": "0.0.0",
        "scripts": {
          "ng": "ng",
          "start": "ng serve --proxy-config proxy.json",
          "build": "ng build",
          "test": "ng test",
          "lint": "ng lint",
          "e2e": "ng e2e"
        },
      ..
      

      Change the Rest URL now pointing to the proxy Server

          URL 'http://localhost:8080/api/auth/test';
      -->
          New URL 'http://localhost:4200/api/auth/test';
      

      Restart the Web Server with: npm start

      Reference

      Angular Layouts

      Passing Data from Component to Component

      Passing Data via HTML

      HTML-Code: common-header.component.html
      
      <p>
         {{headline}}
      <p>
      
      
      Typescript-Code: common-header.component.ts
      export class CommonHeaderComponent implements OnInit {
        @Input() headline: string;
        constructor() { }
      
        ngOnInit() {
        }
      }
      
      Calling HTML-Code: login.component.html
      
      <app-common-header headline='Mein Studium'></app-common-header>
      ...
      
      
      

      Passing Data from Child to Parent

      Parent Typescript Code
      
      receiveMessage($event) {
          this.message = $event;
          console.log('____________________________________  receiveMessage: ' + this.message);
        }
      
      Parent  HTML Code
      
      <app-goals-header headline='Meine Ziele' selectedVal='semesterPlaning' (messageEvent)="receiveMessage($event)"></app-goals-header>
      
      
      CLient Typescript Code
        @Output() messageEvent = new EventEmitter();
      
        sendMessage() {
          this.messageEvent.emit('Hi: ' + this.selectedVal );
        }
      
      

      Reference

      Angular Forms

      Snackbar Sample – Angular 6

      import {MatSnackBar} from '@angular/material';
      ..
      constructor(   public snackBar: MatSnackBar) { }
      .. 
      sendUrgenMessage(errorMessage) {
          const snackBarRef = this.snackBar.open(errorMessage, 'OK',
            {
              duration: 5000,
              panelClass: 'center',
              verticalPosition: 'top'
      
            });
      
          // OK button pressed
          snackBarRef.onAction().subscribe(() => {
            this.logger.error('The snack-bar action was triggered!');
          });
      
        }
      

      Angular Using Date Format

      Typescript-Code

      import { DatePipe } from '@angular/common';
      ..
      getLogTimeStamp(): string {
          // const df1 = 'yyyy-MM-dd hh:mm:ss:SSS';
          const df1 = 'hh:mm:ss:SSS';
          return this.datePipe.transform(new Date(), df1);
        }
      
        sendInfoMessage(m: string) {
          this.message  = this.getLogTimeStamp() + ':: ' + m;
        }
      

      app.module.ts

      import { DatePipe } from '@angular/common';
      
      @NgModule({
        declarations: [
        ...
        ],
        ..
        providers: [
          ...
          DatePipe],
        .. 
      

      Angular and CSS

      Angular HTTP

      Working wiht HTTP Headers

      From Angular Tutorial Chapter: Update headers

      • You can’t directly modify the existing headers within the previous options object because instances of the HttpHeaders class are immutable.
      • Use the set() method instead. It returns a clone of the current instance with the new changes applied.
      • Here’s how you might update the authorization header (after the old token expired) before making the next request.

      The above description isn*’t clear enough whether the original HTTP Headers will get deleted or not !

      Let’ investigate this

      Angular Code

       Adding a Header to the Http GET Request
       getTestPage (): Observable {
          const testUrl1 = 'http://localhost:4200/api/auth/testjwd';
          const requestHeaders = new HttpHeaders().set('Content-Type', 'text/plain');
      
          return this.http.get(testUrl1, {
            headers: requestHeaders
          });
      
      Interceptor Code 
      export class MyFirstInterceptor  implements HttpInterceptor {
      
        intercept(req: HttpRequest, next: HttpHandler) {
          const startTime = Date.now();
          const url = new URL(req.urlWithParams);
          this.logDetails('______Running HTTPRequest ' + url.pathname );
      
          this.dumpHttpHeader(req);
      
          const jwtToken = localStorage.getItem('jwtToken');
      
          if (jwtToken) {
               //  At this stage we need to change HTTP headers but HTTP headers are READ ONLY.
               //  Thats why we need to clone the HTTP request first.
               //  According to
               //  https://stackoverflow.com/questions/45552677/interceptor-angular-4-3-set-multiple-headers-on-the-cloned-request
               //  The code below adds the new Authorization Http to the available Header !
            const cloned = req.clone({
              headers: req.headers.set('Authorization', 'Bearer ' + jwtToken)
            });
            this.logDetails('Sending Page with Authorization Bearer Header - URL:  ' + url.pathname + ' ' + jwtToken );
            this.dumpHttpHeader(cloned);
      
            return next.handle(cloned);
          } else {
              /*
               Shiro should be configured that /api/auth/login is the only URL to be processed without JWT Token
               Simple shiro.ini Sample
                [main]
                  jwtv = de.thnuernberg.in.stuv.phytia.server.security.JWTVerifyingFilter
                [urls]
                  /api/auth/login = anon
                  /api/auth/testjwd = jwtv
                */
            this.logDetails('Sending Login Page without Authorization Bearer Header - URL:   ' + url.pathname );
            return next.handle(req);
          }
        }
      
        private dumpHttpHeader(req: HttpRequest ) {
          const httpHeaders:  HttpHeaders = req.headers;
          const keys = req.headers.keys();
          console.log('__________ Header Count : ' + keys.length );
      
          keys.forEach( key => { console.log (`___ Key:  ${key}  +  ___ Value:  + ${req.headers.get(key)}` ); });
      
        }
      
        private logDetails(msg: string) {
          console.log('__ HTTP Interceptor Message: ' + msg);
        }
      }
      
      

      Log Output

      Inside testpage()  
      http-interceptor.js:55 __ HTTP Interceptor Message: ______Running HTTPRequest /api/auth/testjwd
      http-interceptor.js:51 __________ Header Count : 1
      http-interceptor.js:52 ___ Key:  Content-Type  +  ___ Value:  + text/plain
      http-interceptor.js:55 __ HTTP Interceptor Message: Sending Page with Authorization Bearer Header - URL:  /api/auth/testjwd eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI5OTkiLCJpYXQiOjE1MzMxNDA3NTAsInN1YiI6IkhlbG11dCIsImlzcyI6IlRIIE51ZXJuYmVyZyIsImV4cCI6MTUzMzE0NDM1MH0._rRPzs0kbW1tOLZvLigjfm-63uKo1Sgumny5DcrfR4w
      http-interceptor.js:51 __________ Header Count : 2
      http-interceptor.js:52 ___ Key:  Content-Type  +  ___ Value:  + text/plain
      http-interceptor.js:52 ___ Key:  Authorization  +  ___ Value:  + Bearer eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI5OTkiLCJpYXQiOjE1MzMxNDA3NTAsInN1YiI6IkhlbG11dCIsImlzcyI6IlRIIE51ZXJuYmVyZyIsImV4cCI6MTUzMzE0NDM1MH0._rRPzs0kbW1tOLZvLigjfm-63uKo1Sgumny5DcrfR4w
      

      ANGULAR Materials: mat-button-toggle-group set default selection

      • Initialize the value in ngOnInit() and add the default value to the mat-button-toggle-group HTML line
      Typescript Code: 
      ngOnInit() {
          this.setSelectedVal('generalPlaning');
        }
      
      HTML Code
      
        <mat-button-toggle-group class="goals-button-group" #group="matButtonToggleGroup" <strong>[value]="selectedVal"</strong> (change)="onValChange(group.value)" >
          <mat-button-toggle  class="goals-button"  value="generalPlaning">
            <button mat-button> GeneralPlanung</button>
          </mat-button-toggle>
          <mat-button-toggle class="goals-button"   value="semesterPlaning">
            <button mat-button >SemesterPlanung</button>
          </mat-button-toggle>
        </mat-button-toggle-group>
      
      

      ANGULAR Materials: Using Mat-Dialog

      app.module.ts
      import { MatDialogModule } from '@angular/material/dialog';
      ...
      
      @NgModule({
        declarations: [
           ..
           InfoDialogComponent
           ..
         imports: [
           ..
           MatDialogModule,
           ..
         providers: [
          ..
          InfoDialogComponent]
          ..
      
      Dialog code: info-dialog.components 
      import {Component, Inject, OnInit} from '@angular/core';
      import {MatDialogRef, MAT_DIALOG_DATA} from '@angular/material';
      
      export interface DialogData {
        id: number;
        name: string;
      }
      
      @Component({
        selector: 'app-info-dialog',
        templateUrl: './info-dialog.component.html',
        styleUrls: ['./info-dialog.component.css']
      })
      
      export class InfoDialogComponent implements OnInit {
      
        constructor(
          public dialogRef: MatDialogRef,
          @Inject(MAT_DIALOG_DATA) public data: DialogData) {}
      
        ngOnInit() {
        }
      
        afterClosingInfoDialog() {
            // Validate Dialog Data by  by using a CAST operation.
          const data =  {id: 1, name: 'Info Dialog'};
            // Return the data tp the semester-goal-setting Component
          this.dialogRef.close(data);
        }
      
      }
      
      Component Code 
      import {MatDialog, MatDialogConfig} from '@angular/material';
      ..
       constructor(  ...
                      public infoDialog: MatDialog) {
           ..
         
        openInfoDialog(): void {
          this.logger.warn('StudyProgressComponent:: Opening InfoDialog Dialog ');
          const dialogConfig = new MatDialogConfig();
            // Setting disableClose to true, which means that the user will not be able to close the dialog just by clicking outside of it
            // In short: The user must press the Weiter Button to continue processing
          dialogConfig.disableClose = true;
          const infoDialogRef = this.infoDialog.open(InfoDialogComponent, dialogConfig );
      
          infoDialogRef.afterClosed().subscribe(data => {
            if ( data ) {
              this.logger.warn('StudyProgressComponent:: Closing Dialog: ' + data.name  + ' with Id: ' + data.id);
            } else {
              this.logger.warn('StudyProgressComponent:: Closing Dialog: No Data available ');
            }
          });
        }
      
      

      Reference

      ANGULAR Materials: mat-dialog calls falls in ngAfterViewInit Lifecycle

      Quick Workarounds

      • try moving the code into ngAfterViewInit lifecycle hook
      • try wrapping the code inside the setTimeout [ Fixed my problem ]

      Reference

      ANGULAR Materials: Mat-Grid-List can’t align text left/right

      CSS code to Fix the problem

      CSS Code:
      .align_left {
        width: 100%;
        display: flex;
        align-items: flex-start;
      }
      
      HTML Code: Check for class="align_left" 
      
       <mat-grid-list [cols]="6" rowHeight="50px">
          <mat-grid-tile [colspan]=5 [rowspan]=1 [style.background]="'transparent'"  >
            <div <strong>class="align_left"</strong> >
              <p class="" ><span style="text-align:left;">Lernunterstützung </span></p>
            </div>
          </mat-grid-tile>
        ...
      
      

      ANGULAR Materials: Using MAT-Table with Intellij Throws warning Attribute *matHeaderCellDef is not allowed here

      Warning Attribute *matHeaderCellDef is not allowed here

      D:\dev\myProjects\clone4\dobby-the-companion\src\app\goals\semester-goal-setting\semester-goal-setting.component.html
        Warning:(36, 27) Attribute *matHeaderCellDef is not allowed here
        Warning:(37, 45) Attribute *matCellDef is not allowed here
        Error:(37, 69) 'of' expected
      

      HTML CODE

      
         <table mat-table  #table [dataSource]="dataSource" class="mat-elevation-z8">
      
          </ng-container>
          <!-- Index Column -->
          <ng-container matColumnDef="position">
            <th mat-header-cell *matHeaderCellDef> No. </th>
            <td mat-cell *matCellDef='let element'> {{element.position}} </td>
          </ng-container>
      
      
      

      Reference

      ANGULAR Materials: mat-dialog-container creates a white box with 48×48 px with 24px padding

      CSS Code -> use global styles.css

      
        /* Fix for STUV-197 */
      .no-padding-for-dialog-container .mat-dialog-container {
        padding: 0 !important;
      }
      
      

      Typescript Code -> Use panelClass attribute from MatDialogConfig

        openWarningDialog(): void {
          const dialogConfig = new MatDialogConfig();
          this.disableBagdeButtonFunc();
          dialogConfig.disableClose = true;
          dialogConfig.autoFocus = false;
            // Fix for STUV-197
          dialogConfig.panelClass = ['no-padding-for-dialog-container'];
          const dialogRef = this.warningDialog.open(WarningDialogComponent, dialogConfig);
      
      

      Reference

      ANGULAR Materials: Using Snackbarcomponent

      Snackbar Sample

      Install the related NPMs

      D:\dev\myTestProjects\dobby-the-companion>npm install --save @angular/material @angular/cdk @angular/animations
      npm WARN @angular/animations@6.1.1 requires a peer of @angular/core@6.1.1 but none is installed. You must install peer dependencies yourself.
      npm WARN bootstrap@4.1.1 requires a peer of jquery@1.9.1 - 3 but none is installed. You must install peer dependencies yourself.
      npm WARN bootstrap@4.1.1 requires a peer of popper.js@^1.14.3 but none is installed. You must install peer dependencies yourself.
      npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.4 (node_modules\fsevents):
      npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.4: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
      
      + @angular/cdk@6.4.2
      + @angular/material@6.4.2
      + @angular/animations@6.1.1
      updated 3 packages in 14.633s
      

      Add a Material Theme to global CSS Files src/style.css- Dont forget THIS !

      /* You can add global styles to this file, and also import other style files */
      
      @import '~@angular/material/prebuilt-themes/deeppurple-amber.css';
      

      Re-Install Angular

      D:\dev\myTestProjects\dobby-the-companion> npm uninstall -g @angular/cli
      removed 244 packages in 5.817s
      
      D:\dev\myTestProjects\dobby-the-companion> npm cache clean --force
      npm WARN using --force I sure hope you know what you are doing.
      
      D:\dev\myTestProjects\dobby-the-companion>  npm install -g @angular/cli
      C:\Users\Helmut\AppData\Roaming\npm\ng -> C:\Users\Helmut\AppData\Roaming\npm\node_modules\@angular\cli\bin\ng
      npm WARN rollback Rolling back readable-stream@2.3.6 failed (this is probably harmless): EPERM: operation not permitted, lstat 'C:\Users\Helmut\AppData\Roaming\npm\node_modules\@angular\cli\node_modules\fsevents\node_modules'
      npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.4 (node_modules\@angular\cli\node_modules\fsevents):
      npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.4: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
      
      + @angular/cli@6.1.5
      added 244 packages in 17.228s
      
      D:\dev\myTestProjects\dobby-the-companion> ng -v
      Your global Angular CLI version (6.1.5) is greater than your local
      version (6.1.4). The local Angular CLI version is used.
      
      To disable this warning use "ng config -g cli.warnings.versionMismatch false".
      
           _                      _                 ____ _     ___
          / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
         / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
        / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
       /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                      |___/
      
      
      Angular CLI: 6.1.4
      Node: 8.11.3
      OS: win32 x64
      Angular: 6.1.3
      ... animations, common, compiler, compiler-cli, core, forms
      ... http, language-service, platform-browser
      ... platform-browser-dynamic, router
      
      Package                           Version
      -----------------------------------------------------------
      @angular-devkit/architect         0.7.4
      @angular-devkit/build-angular     0.7.4
      @angular-devkit/build-optimizer   0.7.4
      @angular-devkit/build-webpack     0.7.4
      @angular-devkit/core              0.7.4
      @angular-devkit/schematics        0.7.4
      @angular/cdk                      6.4.5
      @angular/cli                      6.1.4
      @angular/material                 6.4.5
      @ngtools/webpack                  6.1.4
      @schematics/angular               0.7.4
      @schematics/update                0.7.4
      rxjs                              6.2.2
      typescript                        2.9.2
      webpack                           4.9.2
      

      About Angular Logging

      Angular and D3