Using Angular 6

Table of Contents

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