Angular – Tutorial

//Angular – Tutorial

Angular – Tutorial

install nodejs
choco -v
choco install -g typescript@2.9.2 OR npm i -g typescript@2.9.2 for Angular 6.X
npm install -g @angular/cli@6.0

ng -v

mkdir curso-angular2
ng new primeiro-projeto

Open VSCODE
Open Folder with project curso-angular2/primeiro-projeto
Open terminal on VSCode, type: ng serve maybe a error will be displayed

To fix:
Open PowerShell in Admin mode, type:
Set-ExecutionPolicy unrestricted
Unblock-File -Path 'C:\Users\user\AppData\Roaming\npm\ng.ps1' or the path that will show the error above

Another errors are:
ERROR in node_modules/rxjs/internal/types.d.ts(81,44): error TS1005: ';' expected.
node_modules/rxjs/internal/types.d.ts(81,74): error TS1005: ';' expected.
node_modules/rxjs/internal/types.d.ts(81,77): error TS1109: Expression expected.
node_modules/rxjs/internal/types.d.ts(82,52): error TS1005: ';' expected.
node_modules/rxjs/internal/types.d.ts(82,88): error TS1005: ';' expected.
node_modules/rxjs/internal/types.d.ts(82,92): error TS1109: Expression expected.

To fix that run the follow command on the prompt
Directory\curso-angular2\primeiro-projeto>npm install rxjs@6.3.3 --save

good to go


Added your first component manually or by the command line:
ng g c meu-primeiro2
which will create everything for you

uninstall Angular:
npm uninstall -g @angular/cli
npm cache clean --force

how to compile typescript in the terminal: tsc main.ts it will create the script main.js


how to create modules:
ng g m cursos

how to create components
ng g c cursos

ng g c cursos/curso-detalhe

VSCode plugin "Auto Import" for AngularJS

Injecao de dependencia: fornece uma instancia de uma classe
Toda vez que tiver um servico tera o codigo:
@Injectable({  
})


Routes:

app.routing.ts
Content: 
import { PageNotFoundComponentComponent } from './page-not-found-component/page-not-found-component.component';
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { HomeComponent } from './home/home.component';
import { CursosComponent } from './cursos/cursos.component';
import { LoginComponent } from './login/login.component';

const APP_ROUTES: Routes = [
    {
        path: 'cursos', component: CursosComponent
    },
    {
        path: 'login', component: LoginComponent
    },
    {
        path: '', component: HomeComponent
    },
    { 
        // Wildcard route for a 404 page
        path: '**', component: PageNotFoundComponentComponent 
    }
    //{ path: '',   redirectTo: '/first-component', pathMatch: 'full' }, // redirect to `first-component`
];

export const routing: ModuleWithProviders = RouterModule.forRoot(APP_ROUTES);

app.module.ts
import { routing } from './app.routing';
imports: [
    BrowserModule,
    routing
  ],

app.component.html
<h1>Angular Router App</h1>
<!-- This nav gives you links to click, which tells the router which route to use (defined in the routes constant in  AppRoutingModule) -->
<nav>
  <ul>
    <li routerLinkActive="active"><a routerLink="/">Home</a></li>
    <li routerLinkActive="active"><a routerLink="/cursos">Cursos</a></li>
    <li routerLinkActive="active"><a routerLink="/login">Login</a></li>
  </ul>
</nav>

<router-outlet></router-outlet>

Please don't forget to declare all components on app.module.ts section declarations:[]

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

import { routing } from './app.routing';

import { CursosComponent } from './cursos/cursos.component';
import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { LoginComponent } from './login/login.component';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';

@NgModule({
  declarations: [
    AppComponent,
    CursosComponent,
    HomeComponent,
    LoginComponent,
    PageNotFoundComponent
  ],
  imports: [
    BrowserModule,
    routing
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

---------------------//---------------------------------//----------------------------------

How to install Materialize on Angular 6.X
npm install materialize-css --save
npm install @samuelberthe/angular2-materialize --save
npm install jquery@^2.2.4 --save
npm install hammerjs --save

angular.json - Source: https://developer.aliyun.com/mirror/npm/package/@samuelberthe/angular2-materialize/v/1.0.0-rc.2
"build": {          
	"styles": [              
	  "node_modules/materialize-css/dist/css/materialize.css",
	  "src/styles.css"
	],
	"scripts": [              
	  "node_modules/jquery/dist/jquery.js",
	  "node_modules/hammerjs/hammer.js",
	  "node_modules/materialize-css/dist/js/materialize.js"
	]
}

app.module.ts
import { MaterializeModule } from '@samuelberthe/angular2-materialize';
imports: [
   BrowserModule,
   MaterializeModule
],

index.html
<link href="http://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

ng serve --open

How to do data-binding and interpolation with HASH(#) tag?
Below is your code for cursos.component.ts:

import { Component, OnInit } from '@angular/core';
@Component({
  selector: 'app-cursos',
  templateUrl: './cursos.component.html',
  styleUrls: ['./cursos.component.css']
})
export class CursosComponent implements OnInit {  
  constructor() {     
  }
  ngOnInit() {
  }
}

Second using interpolation add your variable inside your template with any event, see example below (cursos.component.html):

Type your name: 
<input type="text" (keyup)="onKeyUp(0)" #myName  />
<br />
<p>
  My name is: {{ myName.value }}
</p>

Route Link Active:
<li routerLinkActive="active"><a routerLink="/login">Login</a></li>

Get Route ID:
curso-detalhes.component.ts
import { ActivatedRoute } from '@angular/router';
import { Component, OnInit } from '@angular/core';
import { Subscription } from 'rxjs';

@Component({
  selector: 'app-curso-detalhes',
  templateUrl: './curso-detalhes.component.html',
  styleUrls: ['./curso-detalhes.component.css']
})
export class CursoDetalhesComponent implements OnInit {

  id: string;
  inscricao: Subscription;

  constructor(private route: ActivatedRoute) { 
    //console.log(this.route);
    //this.id = this.route.snapshot.params["id"];    
  }

  ngOnInit() {
    //inscrever nas mudancas dos parametros
    this.inscricao = this.route.params.subscribe(
    (params: any) => {
      this.id = params['id'];
    });
  }

  ngOnDestroy(){
    this.inscricao.unsubscribe();
  }

}

curso-detalhes.component.html
<p>
  curso-detalhes works! {{ id }}
</p>

app.routing.ts
{
	path: 'curso/:id', component: CursoDetalhesComponent
}

Router Link with Data-Binding
app.componenet.html
...
<li routerLinkActive="active"><a [routerLink]="['curso', idCurso.value]">Curso com Id</a></li>    
...
<div class="container">
  <p>Entre com o curso ID:</p>
  <input (keyup)="onKeyUp(0)"  #idCurso> //must have (keyup)="onKeyUp(0)" this data-binding otherwise does not update idCurso.value on the navbar
  <router-outlet></router-outlet>
</div>

How to add a service in your project:
ng g s cursos/cursos-service
app.module.ts add 
providers: [CursosService],
cursos.componenet.ts add
export class CursosComponent implements OnInit {

  cursos: any[];
  constructor(private CursosService: CursosService) { } //add this

  ngOnInit() {
    this.cursos = this.CursosService.getCursos(); //add this
  }
}

cursos.componenet.html add
<div class="collection">
  <a 
    [routerLink]="['/curso', curso.id]" 
    class="collection-item"
      *ngFor="let curso of cursos">      
      {{ curso.nome }}
    </a>
</div>

If the Curso ID does not exist we will have a new component called curso-nao-encontrado
ng new g c curso-nao-encontrado
app.module.ts 

import { CursosService } from './cursos/cursos.service';
import { MaterializeModule } from '@samuelberthe/angular2-materialize';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { routing } from './app.routing';

import { CursosComponent } from './cursos/cursos.component';
import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { LoginComponent } from './login/login.component';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
import { CursoDetalhesComponent } from './curso-detalhes/curso-detalhes.component';
import { CursoNaEncontratoComponent } from './curso-na-encontrato/curso-na-encontrato.component';

@NgModule({
  declarations: [
    AppComponent,
    CursosComponent,
    HomeComponent,
    LoginComponent,
    PageNotFoundComponent,
    CursoDetalhesComponent,
    CursoNaEncontratoComponent
  ],
  imports: [
    BrowserModule,
    MaterializeModule,
    routing
  ],
  providers: [CursosService],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.routing.ts
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
import { HomeComponent } from './home/home.component';
import { LoginComponent } from './login/login.component';
import { CursosComponent } from './cursos/cursos.component';
import { Routes, RouterModule } from '@angular/router';
import { ModuleWithProviders } from '@angular/core';
import { CursoDetalhesComponent } from './curso-detalhes/curso-detalhes.component';
import { CursoNaEncontratoComponent } from './curso-na-encontrato/curso-na-encontrato.component';

const APP_ROUTES: Routes = [
    {
        path: 'cursos', component: CursosComponent
    },
    {
        path: 'curso/:id', component: CursoDetalhesComponent
    },
    {
        path: 'login', component: LoginComponent
    },
    {
        path: 'naoEncontrado', component: CursoNaEncontratoComponent
    },
    {
        path: '', component: HomeComponent
    },
    { 
        // Wildcard route for a 404 page
        path: '**', component: PageNotFoundComponent 
    }
    //{ path: '',   redirectTo: '/first-component', pathMatch: 'full' }, // redirect to `first-component`
];

export const routing: ModuleWithProviders = RouterModule.forRoot(APP_ROUTES);

cursos.service.ts
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class CursosService {

  constructor() { }

  getCursos(){
    return [
      { id: 1, nome: 'Curso 1'},
      { id: 2, nome: 'Curso 2'},
      { id: 3, nome: 'Curso 3'}
    ]
  }

  getCurso(id:number){
    let cursos = this.getCursos();
    for(let i = 0; i < cursos.length; i++)
    {
      let curso = cursos[i];
      if(curso.id == id){
        return curso;
      }
    }
    return null;
  }
}

curso-detalhes.component.ts
import { CursosService } from './../cursos/cursos.service';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Subscription } from 'rxjs';

@Component({
  selector: 'app-curso-detalhes',
  templateUrl: './curso-detalhes.component.html',
  styleUrls: ['./curso-detalhes.component.css']
})
export class CursoDetalhesComponent implements OnInit {

  id:number;
  inscricao: Subscription;
  curso: any;

  
  constructor(
    private route: ActivatedRoute,
    private router: Router,
    private cursosService: CursosService
    ) {
    //this.id = this.route.snapshot.params['id'];
  }

  ngOnInit() {
    this.inscricao = this.route.params.subscribe(
    (params: any) => {
      this.id = params['id'];
      this.curso = this.cursosService.getCurso(this.id);
      if(this.curso == null){
        this.router.navigate(['naoEncontrado'])
      }
    }
  );  
  }

  ngOnDestroy(){
    this.inscricao.unsubscribe();
  }

}

curso-detalhes.component.html
<p>
  <!--Operador elvis caso seja nulo nao da erro-->
  Curso: {{ curso?.nome }}
</p>

-----------------------------------//---------------------------------------//--------------------------------

How to pass query params in AngularJS
app.component.html

<li routerLinkActive="active"><a routerLink="/cursos" [queryParams]="{pagina:1}">Cursos</a></li>

cursos.componenet.ts

import { CursosService } from './cursos.service';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Subscription } from 'rxjs';

@Component({
  selector: 'app-cursos',
  templateUrl: './cursos.component.html',
  styleUrls: ['./cursos.component.css']
})
export class CursosComponent implements OnInit {

  cursos: any[];
  pagina: number;
  inscricao: Subscription;

  constructor(
    private CursosService: CursosService,
    private route: ActivatedRoute,
    private router: Router
    ) { }

  ngOnInit() {
    this.cursos = this.CursosService.getCursos();
    this.inscricao = this.route.queryParams.subscribe(
      (queryParams: any) => {
        this.pagina = queryParams['pagina'];
      }
    );
  }

  ngOnDestroy(){
    this.inscricao.unsubscribe();
  }
  proximaPagina(){
    //this.pagina++;
    this.router.navigate(['/cursos'], {queryParams: {'pagina': ++this.pagina} } );
  }

}

cursos.component.html
<p>
  cursos works!
</p>
<p>Pagina: {{ pagina }}</p>
<div class="collection">
  <a 
    [routerLink]="['/cursos', curso.id]" 
    class="collection-item"
      *ngFor="let curso of cursos">      
      {{ curso.nome }}
    </a>
</div>

<button (click)="proximaPagina()">Pagination++</button>

------------------------------//---------------------------------//--------------------

Adding Component/Module/Service Alunos

ng g c alunos       
More than one module matches. Use skip-import option to skip importing the component into the closest module.
ng g c alunos --module app //the error above is because I have other modules in the same project
CREATE src/app/alunos/alunos.component.html (25 bytes)
CREATE src/app/alunos/alunos.component.spec.ts (628 bytes)
CREATE src/app/alunos/alunos.component.ts (269 bytes)
CREATE src/app/alunos/alunos.component.css (0 bytes)
UPDATE src/app/app.module.ts (1366 bytes)

It will automatic import on app.module.ts AlunoComponent and add on the NgModule declarations section too.
Next step add a mobule

ng g m alunos //this will create module alunos "alunos.module.ts"
ng g s alunos/alunos //this will create service alunos "alunos.service.ts"
ng g m alunos --routing //this will create module alunos "alunos.module.ts" and alunos-routing.module.ts
ng g c alunos/aluno-detalhes
ng g c alunos/aluno-formulario

Always add the new component on alunos.module.ts declarations: [] section

Any module has:
declarations: [ NameComponent ],
imports: [ NameModule, NameRoutingModule ],
providers: [ NameService ]

After adding alunos-routing.module.ts you will have to add this route on app.component.html
<li routerLinkActive="active"><a [routerLink]="['alunos']">Alunos</a></li> OR
<li routerLinkActive="active"><a routerLink="/alunos">Alunos</a></li>

on app.module.ts add imports: [ AlunosModule ]

How to create children routes: /alunos/novo or /alunos/id

file: alunos-routing.module.ts add children option

import { AlunoDetalhesComponent } from './aluno-detalhes/aluno-detalhes.component';
import { AlunoFormularioComponent } from './aluno-formulario/aluno-formulario.component';
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AlunosComponent } from './alunos.component';

const alunosRoutes: Routes = [
  {
    path: 'alunos', component: AlunosComponent, children:[
      {
        path: 'novo', component: AlunoFormularioComponent
      },
      {
        path: ':id', component: AlunoDetalhesComponent
      },
      {
        path: ':id/editar', component: AlunoFormularioComponent
      }
    ]
  }
];

@NgModule({
  imports: [RouterModule.forChild(alunosRoutes)],
  exports: [RouterModule]
})
export class AlunosRoutingModule { }

on alunos.component.html add:
<router-outlet></router-outlet>

how to list alunos in your screen:
alunos.component.html
<div class="row">
<p>
  List of Students
</p>

<div class="col s6">
  <div class="collection">
    <a class="collection-item"
    *ngFor="let aluno of alunos"
    [routerLink]="[aluno.id]">    
    {{ aluno.nome }}
    </a>
  </div>  
</div>
<router-outlet></router-outlet>
</div>

alunos.service.ts
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class AlunosService {

  private alunos: any[] = [
    { id: 1, nome: 'Aluno 01', email: 'aluno01@email.com' },
    { id: 2, nome: 'Aluno 02', email: 'aluno02@email.com' },
    { id: 3, nome: 'Aluno 03', email: 'aluno03@email.com' }
  ];

  getAlunos(){
    return this.alunos;
  }

  constructor() { }
}

alunos.component.html
import { AlunosService } from './alunos.service';
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-alunos',
  templateUrl: './alunos.component.html',
  styleUrls: ['./alunos.component.css']
})
export class AlunosComponent implements OnInit {

  private alunos: any[] = [];
  constructor( private alunosService: AlunosService) { }

  ngOnInit() {
    this.alunos = this.alunosService.getAlunos();
  }

}

-----------------------------//--------------------

Adding Aluno Details
aluno-detalhes.component.html
<p>
  Student Details
</p>

<p>Id: {{ aluno.id }}</p>
<p>Name: {{ aluno.nome }}</p>
<p>Email: {{ aluno.email }}</p>

aluno-detalhes.component.ts
import { AlunosService } from './../alunos.service';
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';
import { ActivatedRoute, Router } from '@angular/router';

@Component({
  selector: 'app-aluno-detalhes',
  templateUrl: './aluno-detalhes.component.html',
  styleUrls: ['./aluno-detalhes.component.css']
})
export class AlunoDetalhesComponent implements OnInit, OnDestroy {

  aluno: any;
  inscricao: Subscription;

  constructor(
    private route: ActivatedRoute,
    private router: Router,
    private alunosService: AlunosService
    ) { }

  ngOnInit() {
    this.inscricao = this.route.params.subscribe(
      (params: any) => {
        let id = params['id'];
        this.aluno = this.alunosService.getAluno(id);
      }
    )
  }

  editarContato(){
    this.router.navigate(['/alunos', this.aluno.id, 'editar']);
  }

  ngOnDestroy(){
    this.inscricao.unsubscribe();
  }

}

aluno-detalhes.component.html
<p>
  Student Details
</p>

<p>Id: {{ aluno.id }}</p>
<p>Name: {{ aluno.nome }}</p>
<p>Email: {{ aluno.email }}</p>

<a class="waves-effect waves-light btn" (click)="editarContato()">Editar</a>


alunos.service.ts
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class AlunosService {

  private alunos: any[] = [
    { id: 1, nome: 'Aluno 01', email: 'aluno01@email.com' },
    { id: 2, nome: 'Aluno 02', email: 'aluno02@email.com' },
    { id: 3, nome: 'Aluno 03', email: 'aluno03@email.com' }
  ];

  getAlunos(){
    return this.alunos;
  }
  getAluno(id: number){
    for(let i=0; i<this.alunos.length;i++){
      let aluno = this.alunos[i];
      if(aluno.id == id){
        return aluno;
      }      
    }
    return null;
  }

  constructor() { }
}


--------------------//-------------------------//-------------------
How to make a Login
ng g c login
ng g s login/auth
add file /login/usuario.ts

script for auth.service.ts:
import { Usuario } from './usuario';
import { Injectable, EventEmitter } from '@angular/core';
import { Router } from '@angular/router';

@Injectable({
  providedIn: 'root'
})
export class AuthService {

  private usuarioAutenticato: boolean = false;
  
  mostrarMenuEmitter = new EventEmitter<boolean>();

  fazerLogin(usuario: Usuario){
    if(usuario.email == 'usuario@email.com' && usuario.password === '123456'){
      this.usuarioAutenticato = true;

      this.mostrarMenuEmitter.emit(true);

      this.router.navigate(['/']);
    }else{      
      this.usuarioAutenticato = false;

      this.mostrarMenuEmitter.emit(false);
    }
  }

  constructor(private router: Router) { }
}

script usuario.ts

export class Usuario{
    email: string;
    password: string;
}

script login.component.ts
import { FormsModule } from '@angular/forms';
import { AuthService } from './auth.service';
import { Usuario } from './usuario';
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {

  private usuario: Usuario = new Usuario();

  constructor(private authService: AuthService) { }

  fazerLogin(){
    console.log(this.usuario);
    this.authService.fazerLogin(this.usuario);
  }

  ngOnInit() {
  }

}

script login.component.html
<div class="row">
  <div class="input-field col s12">
    <input [(ngModel)]="usuario.email" id="email" type="email" class="validate">
    <label for="email">Email</label>
  </div>
</div>
<div class="row">
  <div class="input-field col s12">
    <input [(ngModel)]="usuario.password" id="password" type="password" class="validate">
    <label for="password">Password</label>
  </div>
</div>


<button class="btn waves-effect waves-light" type="submit" name="action" (click)="fazerLogin()" >Submit
  <i class="material-icons right">send</i>
</button>

script app.component.html
<nav *ngIf="mostrarMenu">
  <ul>
    <li routerLinkActive="active"><a routerLink="/">Home</a></li>
    <li routerLinkActive="active"><a routerLink="/login">Login</a></li>
    <li routerLinkActive="active"><a routerLink="/cursos" [queryParams]="{pagina:1}">Cursos</a></li>
    <li routerLinkActive="active"><a [routerLink]="['curso', idCurso.value]">Curso com Id</a></li>    
    <li routerLinkActive="active"><a [routerLink]="['alunos']">Alunos</a></li>
  </ul>
</nav>

<div class="container">
  <p>Entre com o curso ID: {{ idCurso.value }}</p>
  <input (keyup)="onKeyUp(0)"  #idCurso>
  <router-outlet></router-outlet>
</div>

script app.component.ts
import { AuthService } from './login/auth.service';
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'app';

  mostrarMenu: boolean = false;

  constructor(private authService: AuthService){

  }

  ngOnInit(){
    this.authService.mostrarMenuEmitter.subscribe(
      mostrar => this.mostrarMenu = mostrar
    );
  }

}


----------------------------//-------------------------------//---------------------
Login Screen with Route Authentication


ng g guard guards/auth 

script auth.guard.ts:
import { AuthService } from './../login/auth.service';
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate {
  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ) : Observable<boolean> | boolean {
    
      console.log('auth.guard.ts');

      if(this.authService.usuarioEstaAutenticado()){
        return true;
      }
  
      this.router.navigate(['/login']);
      
      return false;
  }

  
  constructor(
    private authService: AuthService,
    private router: Router
  ) { 
  }

}

app.routing.module.ts
import { AlunosComponent } from './alunos/alunos.component';
import { CursosComponent } from './cursos/cursos.component';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
import { HomeComponent } from './home/home.component';
import { LoginComponent } from './login/login.component';
import { Routes, RouterModule } from '@angular/router';
import { NgModule } from '@angular/core';
import { AuthGuard } from './guards/auth.guard';

const appRoutes: Routes = [        
    {
        path: 'login', component: LoginComponent
    },
    {
        path: '', 
        component: HomeComponent,
        canActivate: [AuthGuard]  //add this
    },
    { 
        // Wildcard route for a 404 page
        path: '**', component: PageNotFoundComponent 
    }
    //{ path: '',   redirectTo: '/first-component', pathMatch: 'full' }, // redirect to `first-component`
];

@NgModule(
    {
        imports: [RouterModule.forRoot(appRoutes)],
        exports: [RouterModule]
    }
)

export class AppRoutingModule{} 

login/auth.service.ts
import { Usuario } from './usuario';
import { Injectable, EventEmitter } from '@angular/core';
import { Router } from '@angular/router';

@Injectable({
  providedIn: 'root'
})
export class AuthService {

  private usuarioAutenticato: boolean = false;
  
  mostrarMenuEmitter = new EventEmitter<boolean>();

  fazerLogin(usuario: Usuario){
    if(usuario.email == 'usuario@email.com' && usuario.password === '123456'){
      this.usuarioAutenticato = true;

      this.mostrarMenuEmitter.emit(true);

      this.router.navigate(['/']);
    }else{      
      this.usuarioAutenticato = false;

      this.mostrarMenuEmitter.emit(false);
    }
  }

  usuarioEstaAutenticado(){
    return this.usuarioAutenticato;
  }

  constructor(private router: Router) { }
}

app.module.ts
import { AuthService } from './login/auth.service';
import { FormsModule } from '@angular/forms';
import { AlunosModule } from './alunos/alunos.module';
import { AppRoutingModule } from './app.routing.module';
import { CursosModule } from './cursos/cursos.module';
import { MaterializeModule } from '@samuelberthe/angular2-materialize';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

//import { routing } from './app.routing';
import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { LoginComponent } from './login/login.component';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
import { AuthGuard } from './guards/auth.guard';
//import { AlunosComponent } from './alunos/alunos.component';
//import { CursoDetalhesComponent } from './cursos/curso-detalhes/curso-detalhes.component';
//import { CursosComponent } from './cursos/cursos.component';
///import { CursoNaEncontratoComponent } from './cursos/curso-na-encontrato/curso-na-encontrato.component';

@NgModule({
  declarations: [
    AppComponent,
    //CursosComponent,
    HomeComponent,
    LoginComponent,
    PageNotFoundComponent
    //AlunosComponent
    //CursoDetalhesComponent,
    //CursoNaEncontratoComponent
  ],
  imports: [
    BrowserModule,
    MaterializeModule,
    CursosModule,
    AlunosModule,
    FormsModule,
    AppRoutingModule
  ],
  providers: [ 
    AuthService, 
    AuthGuard
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }


-------------------//-----------------------//-----------------
How to add authentication for module Cursos without having children in cursos.module.routing.ts
ng g guard guards/cursos

guards/cursos.guard.ts
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class CursosGuard implements CanActivate {
  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
      console.log('CursosGuard');
      console.log('guarda de rota filha');
      return true;
  }
}

cursos/cursos.module.routing.ts
import { Routes, RouterModule } from '@angular/router';
import { NgModule } from '@angular/core';

import { CursosComponent } from './cursos.component';
import { CursoDetalhesComponent } from './curso-detalhes/curso-detalhes.component';
import { CursoNaEncontratoComponent } from './/curso-na-encontrato/curso-na-encontrato.component';
import { AuthGuard } from '../guards/auth.guard';

const cursosRoutes: Routes = [
    {
        path: 'cursos', component: CursosComponent, canActivate: [AuthGuard]
    },    
    {
        path: 'cursos/:id', component: CursoDetalhesComponent, canActivate: [AuthGuard]
    },
    {
        path: 'naoEncontrado', component: CursoNaEncontratoComponent 
    }   
];

@NgModule(
    {
        imports: [RouterModule.forChild(cursosRoutes)],
        exports: [RouterModule]
    }
)

export class CursosRoutingModule {}

curso.module.ts
import { NgModule } from "@angular/core";
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';

import { CursosService } from './cursos.service';
import { CursoNaEncontratoComponent } from './curso-na-encontrato/curso-na-encontrato.component';
import { CursoDetalhesComponent } from './curso-detalhes/curso-detalhes.component';
import { CursosComponent } from './cursos.component';
import { CursosRoutingModule } from "./cursos.routing.module";

@NgModule({
    imports: [
        CommonModule,        
        RouterModule,
        CursosRoutingModule
    ],
    exports: [],
    declarations: [
        CursosComponent,
        CursoDetalhesComponent,
        CursoNaEncontratoComponent
    ],
    providers: [CursosService]
})

export class CursosModule {};

ng g guard guards/cursos will generate cursos.guard.ts

script for guards/cursos.guard.ts:
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class CursosGuard implements CanActivate {
  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
      console.log('CursosGuard');
      console.log('guarda de rota filha');
      return true;
  }
}

---------//-------------------//---------------------------------//--------------------
How to add authentication for module Cursos with children in cursos.module.routing.ts
ng g guard guards/cursos

cursos.routing.module.ts
import { CursoFormularioComponent } from './curso-formulario/curso-formulario.component';
import { CursosGuard } from './../guards/cursos.guard';
import { Routes, RouterModule } from '@angular/router';
import { NgModule } from '@angular/core';

import { CursosComponent } from './cursos.component';
import { CursoDetalhesComponent } from './curso-detalhes/curso-detalhes.component';
import { CursoNaEncontratoComponent } from './/curso-na-encontrato/curso-na-encontrato.component';
import { AuthGuard } from '../guards/auth.guard';
import { CursosDeactivateGuard } from '../guards/cursos-deactivate.guard';

const cursosRoutes: Routes = [
    {
        path: 'cursos', 
        component: CursosComponent,    
        canActivate: [AuthGuard], 
        canActivateChild: [CursosGuard],
        children: [            
            {
                path: ':id', 
                component: CursoDetalhesComponent
            },
            {
                path: ':id/editar', 
                component: CursoFormularioComponent
            }
        ]
    }
];

@NgModule(
    {
        imports: [RouterModule.forChild(cursosRoutes)],
        exports: [RouterModule]
    }
)

export class CursosRoutingModule {}

guards/cursos.guard.ts
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, RouterStateSnapshot, CanActivateChild } from '@angular/router';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class CursosGuard implements CanActivateChild {
  canActivateChild(
    next: ActivatedRouteSnapshot, 
    state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
      console.log('guarda de rota filha cursos');
      return true;
  }
}

cursos.module.ts
providers: [CursosService, CursosGuard]

cursos.component.html
<p>
  cursos works!
</p>
<p>Pagina: {{ pagina }}</p>
<div class="collection">
  <a 
    [routerLink]="['/cursos', curso.id]" 
    class="collection-item"
      *ngFor="let curso of cursos">      
      {{ curso.nome }}
    </a>
</div>

<button (click)="proximaPagina()">Pagination++</button>

<router-outlet></router-outlet>

-----------------------------//---------------------------------//--------------------

update angular cli
npm uninstall -g angular-cli @angular/cli
npm cache cleannpm install -g @angular/cli@latest

---------//-------------------//---------------------------------//--------------------

How to lock user in a form after making form updates - CanDeactivate - after updating some data in a form the user will receive a message if really wants to loose all data input.

add component ng g c cursos/curso-formulario
curso-formulario.componenet.ts
import { CursosService } from './../cursos.service';
import { ActivatedRoute } from '@angular/router';
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';

@Component({
  selector: 'app-curso-formulario',
  templateUrl: './curso-formulario.component.html',
  styleUrls: ['./curso-formulario.component.css']
})
export class CursoFormularioComponent implements OnInit, OnDestroy {

  curso: any;
  inscricao: Subscription;
  private formMudou:boolean = false;

  constructor(
    private route: ActivatedRoute,
    private cursoService: CursosService
    ) { }

  ngOnInit() {
    this.inscricao = this.route.params.subscribe(
      (params: any) => {
        let id = params['id'];
        this.curso = this.cursoService.getCurso(id);
        if(this.curso === null){
          this.curso = {};
        }
      }
    )
  }

  ngOnDestroy(){
    this.inscricao.unsubscribe();
  }

  onInput(){
    this.formMudou = true;
  }

  podeMudarRota(){

    if(this.formMudou)
    {
      if(confirm('Tem certeza que deseja sair dessa pagina?')){
        return true;
      }else{
        return false;
      }
    }

    return true;
  }
}

cursos/curso-formulario.component.html
<h5>
  Add/Edit Curso
</h5>

<div class="col s12">
  <div class="row">
    <div class="input-field col s12">
      <input disabled [(ngModel)]="curso.id" id="disabled" type="text">
      <label for="disabled">#</label>
    </div>
  </div>
  <div class="row">
    <div class="input-field col s12">
      <input [(ngModel)]="curso.nome" id="nome" class="validate" (input)="onInput()">
      <label for="nome" class="active">Name</label>
    </div>
  </div>
</div>

add file cursos/cursos-deactivate.guard.ts
import { CursoFormularioComponent } from './../cursos/curso-formulario/curso-formulario.component';
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, RouterStateSnapshot, CanDeactivate } from '@angular/router';
import { Observable } from 'rxjs';
import { of } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class CursosDeactivateGuard implements CanDeactivate<CursoFormularioComponent> {
    canDeactivate(
      component: CursoFormularioComponent,
      currentRoute: ActivatedRouteSnapshot, 
      currentState: RouterStateSnapshot
    ): Observable<boolean>|Promise<boolean>|boolean {

      console.log('guarda de desativacao cursos');
      
      return component.podeMudarRota();
    }
}

cursos/curso-detalhes.component.html
<p>
  curso-detalhes works! {{ id }}
</p>
<p>
  <!--Operador elvis caso seja nulo nao da erro-->
  Curso: {{ curso?.nome }}
</p>

<a class="waves-effect waves-light btn" (click)="editarContato()">Editar</a> 

cursos/curso-detalhes.component.ts
import { CursosService } from '../cursos.service';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Subscription } from 'rxjs';

@Component({
  selector: 'app-curso-detalhes',
  templateUrl: './curso-detalhes.component.html',
  styleUrls: ['./curso-detalhes.component.css']
})
export class CursoDetalhesComponent implements OnInit {

  id:number;
  inscricao: Subscription;
  curso: any;

  
  constructor(
    private route: ActivatedRoute,
    private router: Router,
    private cursosService: CursosService
    ) {
    //this.id = this.route.snapshot.params['id'];
  }

  ngOnInit() {
    this.inscricao = this.route.params.subscribe(
    (params: any) => {
      this.id = params['id'];
      this.curso = this.cursosService.getCurso(this.id);      
      if(this.curso == null){
        this.router.navigate(['naoEncontrado'])
      }
    }
  );  
  }

  ngOnDestroy(){
    this.inscricao.unsubscribe();
  }

  editarContato(){
    this.router.navigate(['/cursos', this.curso.id, 'editar']);
  }

}

cursos.module.ts 

import { FormsModule } from '@angular/forms';
import { CursosGuard } from './../guards/cursos.guard';
import { NgModule } from "@angular/core";
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';

import { CursosService } from './cursos.service';
import { CursoNaEncontratoComponent } from './curso-na-encontrato/curso-na-encontrato.component';
import { CursoDetalhesComponent } from './curso-detalhes/curso-detalhes.component';
import { CursosComponent } from './cursos.component';
import { CursosRoutingModule } from "./cursos.routing.module";
import { CursoFormularioComponent } from './curso-formulario/curso-formulario.component';

@NgModule({
    imports: [
        CommonModule,
        FormsModule,
        CursosRoutingModule
    ],
    exports: [],
    declarations: [
        CursosComponent,
        CursoDetalhesComponent,
        CursoNaEncontratoComponent,
        CursoFormularioComponent
    ],
    providers: [CursosService, CursosGuard]
})

export class CursosModule {};

cursos.routing.module.ts add canDeactivate: [CursosDeactivateGuard] authentication in cursos childrens that you wanna have their page locked

import { CursoFormularioComponent } from './curso-formulario/curso-formulario.component';
import { CursosGuard } from './../guards/cursos.guard';
import { Routes, RouterModule } from '@angular/router';
import { NgModule } from '@angular/core';

import { CursosComponent } from './cursos.component';
import { CursoDetalhesComponent } from './curso-detalhes/curso-detalhes.component';
import { CursoNaEncontratoComponent } from './/curso-na-encontrato/curso-na-encontrato.component';
import { AuthGuard } from '../guards/auth.guard';
import { CursosDeactivateGuard } from '../guards/cursos-deactivate.guard';

const cursosRoutes: Routes = [
    {
        path: 'cursos', 
        component: CursosComponent,    
        canActivate: [AuthGuard], 
        canActivateChild: [CursosGuard],
        children: [            
            {
                path: ':id', 
                component: CursoDetalhesComponent
            },
            {
                path: ':id/editar', 
                component: CursoFormularioComponent,
                canDeactivate: [CursosDeactivateGuard]
            }
        ]
    }
];

@NgModule(
    {
        imports: [RouterModule.forChild(cursosRoutes)],
        exports: [RouterModule]
    }
)

export class CursosRoutingModule {}


------------------------------//--------------------------------------//-----------------------------
How to create a service in a project
ng new angular-project-service
cd angular-project-service
npm install rxjs@6.3.3 --save
ng g c cursos
ng g s cursos/cursos
ng serve

add script on app.component.html (comes from cursos.component.ts selector):
<app-cursos></app-cursos>

add script on cursos.service.ts
export class CursosService {

  cursos: string[] = [ 
    'Curso 1', 'Curso 2', 'Curso 3'
  ];

  getCursos(){
    return this.cursos;
  }  
}

add script cursos.component.ts
import { CursosService } from './cursos.service';
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-cursos',
  templateUrl: './cursos.component.html',
  styleUrls: ['./cursos.component.css']
})
export class CursosComponent implements OnInit {

  cursos: string[] = [];
  cursosService: CursosService

  constructor() { 
    this.cursosService = new CursosService();
  }

  ngOnInit() {
    this.cursos = this.cursosService.getCursos();
  }

}

add script cursos.componenet.html
<p>
  cursos works!
</p>
<ul>
  <li *ngFor="let curso of cursos">
    {{ curso }}
  </li>
</ul>

------------------------------//--------------------------------------//-----------------------------

How to create a service with dependency injection?

Class 1 <- Class 2
Inject an instance of Class2 in Class1 using method set, attributes or constructors.

add script cursos.service.ts
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class CursosService {

  cursos: string[] = [ 
    'Curso 1', 'Curso 2', 'Curso 3'
  ];
  constructor() { }

  getCursos(){
    return this.cursos;
  }  
}

add script on cursos.component.ts:
import { CursosService } from './cursos.service';
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-cursos',
  templateUrl: './cursos.component.html',
  styleUrls: ['./cursos.component.css']
})
export class CursosComponent implements OnInit {

  cursos: string[] = [];
  cursosService: CursosService

  constructor(cursosService: CursosService ) { 
    //this.cursosService = new CursosService(); 
    this.cursosService = cursosService;
  }

  ngOnInit() {
    this.cursos = this.cursosService.getCursos();
  }

}

add script on app.module.ts:
import { CursosService } from './cursos/cursos.service';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { CursosComponent } from './cursos/cursos.component';

@NgModule({
  declarations: [
    AppComponent,
    CursosComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [CursosService], //Any Service with DI goes into the providers:[] that will be available for the whole application
  bootstrap: [AppComponent]
})
export class AppModule { }

to make DI better add private inside the constructor which will automatic create the variable 

cursos.component.ts
import { CursosService } from './cursos.service';
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-cursos',
  templateUrl: './cursos.component.html',
  styleUrls: ['./cursos.component.css']
})
export class CursosComponent implements OnInit {

  cursos: string[] = [];
  //cursosService: CursosService

  constructor(private cursosService: CursosService ) { 
    //this.cursosService = new CursosService(); 
    //this.cursosService = cursosService;
  }

  ngOnInit() {
    this.cursos = this.cursosService.getCursos();
  }

}

Every Class added in the providers section o app.module.ts will always generate only one instance.
------------------------------//--------------------------------------//-----------------------------

Singleton Pattern - only one instance

ng g m cursos
script to add on cursos.module.ts:
import { CursosService } from './cursos.service';
import { CursosComponent } from './cursos.component';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

@NgModule({
  imports: [
    CommonModule
  ],
  declarations: [CursosComponent],
  exports: [CursosComponent],
  providers: [CursosService]
})
export class CursosModule { }

ng g c criar-cursos
ng g m criar-cursos

script to add on app.component.html
<app-criar-cursos></app-criar-cursos>
<br />
<app-cursos></app-cursos>

criar-cursos.component.html
<p>
  criar-cursos works!
</p>
<ul>
  <li *ngFor="let curso of cursos">
    {{ curso }}
  </li>
</ul>

script to add on criar-cursos.component.ts
import { CursosService } from './../cursos/cursos.service';
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-criar-cursos',
  templateUrl: './criar-cursos.component.html',
  styleUrls: ['./criar-cursos.component.css']
})
export class CriarCursosComponent implements OnInit {
  
  cursos: string[] = [];

  constructor(private cursosService: CursosService ) { 
  }

  ngOnInit() {
    this.cursos = this.cursosService.getCursos();
  }


}

script to add on criar-cursos.module.ts
import { CursosService } from './../cursos/cursos.service';
import { CriarCursosComponent } from './criar-cursos.component';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

@NgModule({
  imports: [
    CommonModule
  ],
  declarations: [CriarCursosComponent],
  exports: [CriarCursosComponent], //need to export the component so other areas have access
  providers: [CursosService]
})
export class CriarCursosModule { }

script to add on app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';

import { CursosModule } from './cursos/cursos.module';
import { CriarCursosModule } from './criar-cursos/criar-cursos.module';

@NgModule({
  declarations: [
    AppComponent //we remove CursosComponent and CriarCursosComponent from here
  ],
  imports: [
    BrowserModule,
    CursosModule, //we add the new modules here, CursosModule and CriarCursosModule
    CriarCursosModule
  ],
  providers: [], //we remove CursosService from here and with that CursosService is still having just one instance, if you declare here has global scope
  bootstrap: [AppComponent]
})
export class AppModule { }

In this example you will see that CursosService has just one instance - Constructor is called just one time for the whole applciation
This is the patern Singleton.

If you want to have multiple instances you must declare @Component({ selector: '', teplateUrl: '', styleUrls: '', providers: [CursosService] }) each component that wants to have a new instance

@Component({
  selector: 'app-cursos',
  templateUrl: './cursos.component.html',
  styleUrls: ['./cursos.component.css'],
  providers: [CursosService]
})

AND

@Component({
  selector: 'app-criar-cursos',
  templateUrl: './criar-cursos.component.html',
  styleUrls: ['./criar-cursos.component.css'],
  providers: [CursosService]
})

You will have just one instance for each component

------------------------------//--------------------------------------//-----------------------------

How to share data between components using services when you have multiples instances of same class like the example above.
Can't be used @Input or @Output properties because in this example we will not have component fater and children.

cursos.service.ts
import { Injectable, Output } from '@angular/core';
import { EventEmitter } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class CursosService {

  emitirCursoCriado = new EventEmitter<string>();

  cursos: string[] = [ 
    'Curso 1', 'Curso 2', 'Curso 3'
  ];
  constructor() {
    console.log('Constructor CursosService');
   }

  getCursos(){
    return this.cursos;
  }  

  addCurso(curso: string){
    this.cursos.push(curso);
    this.emitirCursoCriado.emit(curso);
  }
}

Must import EventEmitter that is part of @angular/core package

cursos.component.ts
import { CursosService } from './cursos.service';
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-cursos',
  templateUrl: './cursos.component.html',
  styleUrls: ['./cursos.component.css'],
  providers: [CursosService]
})
export class CursosComponent implements OnInit {

  cursos: string[] = [];
  //cursosService: CursosService

  constructor(private cursosService: CursosService ) { 
    //this.cursosService = new CursosService(); 
    //this.cursosService = cursosService;
  }

  ngOnInit() {

    this.cursos = this.cursosService.getCursos();

    this.cursosService.emitirCursoCriado.subscribe(
      (curso) => {console.log(curso)}
    );
    
  }
}

ng g c receber-curso-criado

This component wil be in app.module.ts, but we don't want that. We want to have this new 
component hookup with criar-cursos

app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';

import { CursosModule } from './cursos/cursos.module';
import { CriarCursosModule } from './criar-cursos/criar-cursos.module';
//import { ReceberCursoCriadoComponent } from './receber-curso-criado/receber-curso-criado.component';

@NgModule({
  declarations: [
    AppComponent
    //ReceberCursoCriadoComponent //disable this line
  ],
  imports: [
    BrowserModule,
    CursosModule,
    CriarCursosModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }


add script on criar-cursos/criar-cursos.module.ts
import { ReceberCursoCriadoComponent } from './../receber-curso-criado/receber-curso-criado.component';
import { CursosService } from './../cursos/cursos.service';
import { CriarCursosComponent } from './criar-cursos.component';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

@NgModule({
  imports: [
    CommonModule
  ],
  declarations: [CriarCursosComponent, ReceberCursoCriadoComponent],
  exports: [CriarCursosComponent],
  providers: [CursosService]
})
export class CriarCursosModule { }


add script on criar-cursos.component.html (add selector)
<p>
  criar-cursos works!
</p>

<input type="text" #cursoInput>
<button (click)="onAddCurso(cursoInput.value)">Add Curso</button>

<ul>
  <li *ngFor="let curso of cursos">
    {{ curso }}
  </li>
</ul>

<app-receber-curso-criado></app-receber-curso-criado>


add script on receber-curso-criado.component.ts

import { CursosService } from './../cursos/cursos.service';
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-receber-curso-criado',
  templateUrl: './receber-curso-criado.component.html',
  styleUrls: ['./receber-curso-criado.component.css']
})
export class ReceberCursoCriadoComponent implements OnInit {

  curso: string;

  constructor(private cursosService: CursosService) { }

  ngOnInit() {
    this.cursosService.emitirCursoCriado.subscribe(
      (cursoCriado) => { this.curso = cursoCriado }
    );
  }

}

add script on receber-curso-criado.component.html

<p *ngIf="curso">
  O ultimo curso criado foi: {{ curso }}
</p>

The result that you will have is the broadcast message between father component and child, but
you still don't have the messages being exchange with the other list
What you will have to do?You will have to create a static EventEmitter that will have access anywhere in the application

cursos.service.ts
import { Injectable, Output } from '@angular/core';
import { EventEmitter } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class CursosService {

  emitirCursoCriado = new EventEmitter<string>();

  static emitirNovoCurso = new EventEmitter<string>(); //add word STATIC here

  cursos: string[] = [ 
    'Curso 1', 'Curso 2', 'Curso 3'
  ];
  constructor() {
    console.log('Constructor CursosService');
   }

  getCursos(){
    return this.cursos;
  }  

  addCurso(curso: string){
    this.cursos.push(curso);
    this.emitirCursoCriado.emit(curso);
    CursosService.emitirNovoCurso.emit(curso); //add this
  }
}


add script on cursos.component.ts
import { CursosService } from './cursos.service';
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-cursos',
  templateUrl: './cursos.component.html',
  styleUrls: ['./cursos.component.css'],
  providers: [CursosService]
})
export class CursosComponent implements OnInit {

  cursos: string[] = [];
  //cursosService: CursosService

  constructor(private cursosService: CursosService ) { 
    //this.cursosService = new CursosService(); 
    //this.cursosService = cursosService;
  }

  ngOnInit() {

    this.cursos = this.cursosService.getCursos();

    //this.cursosService.emitirCursoCriado.subscribe(
    //  (curso) => {console.log(curso)}
    //);

	//Call the Static Method throw class name
    CursosService.emitirNovoCurso.subscribe(
      (curso) => { 
        this.cursos.push(curso);
        console.log(curso); 
      }
    );

  }
}

------------------------------//--------------------------------------//-----------------------------

How to call a service inside other service?
ng g s shared/log  
shared/log.service.ts
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class LogService {

  constructor() { }

  consoleLog(msg: string){
    console.log(msg);
  }
}

cursos/cursos.service.ts
import { LogService } from './../shared/log.service';
import { Injectable, Output } from '@angular/core';
import { EventEmitter } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class CursosService {

  emitirCursoCriado = new EventEmitter<string>();

  static emitirNovoCurso = new EventEmitter<string>();

  cursos: string[] = [ 
    'Curso 1', 'Curso 2', 'Curso 3'
  ];
  constructor(private logService: LogService ) { //add logService in the constructor
    console.log('Constructor CursosService');
   }

  getCursos(){
    this.logService.consoleLog('getCursos();');
    return this.cursos;
  }  

  addCurso(curso: string){
    this.logService.consoleLog(`Criando um novo Curso ${curso}`); //templates literals ECMA script 2015
    this.cursos.push(curso);
    this.emitirCursoCriado.emit(curso);
    CursosService.emitirNovoCurso.emit(curso);
  }
}


------------------------------//--------------------------------------//-----------------------------
Pipes are filters
Module that contain all Pipes is BrowserModule which is imported in app.module.ts

ng g c livro

add script livro.component.ts
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-livro',
  templateUrl: './livro.component.html',
  styleUrls: ['./livro.component.css']
})
export class LivroComponent implements OnInit {

  livro: any = {
    titulo: 'Learning',
    rating: 5.23123,
    preco: 23.53,
    dataLancamento: new Date(2016, 5, 23),
    url: 'http://a.co/glqjpRP'
  };
  
  constructor() { }

  ngOnInit() {
  }

}


add script livro.component.html

<p>
  Livro Titulo: {{ livro.titulo | uppercase }}
</p>

<p>
  Ratings: {{ livro.rating | number:'1.1-1' }}
</p>

<p>
  Preco: {{ livro.preco | currency:'BRL':true }}
</p>

<p>
  URL: {{ livro.url }}
</p>

<p>
  JSON: {{ livro | json }}
</p>


------------------------------//--------------------------------------//-----------------------------
How to create a Pipe?

ng g p livro/camelCase

add pipe script on livro.component.html (camelCase)
<p>
  Livro Titulo: {{ livro.titulo | uppercase | lowercase | camelCase }}
</p>

<p>
  Ratings: {{ livro.rating | number:'1.1-1' }}
</p>

<p>
  Preco: {{ livro.preco | currency:'BRL':true }}
</p>

<p>
  Data de lancamento: {{ livro.dataLancamento | date:'dd-MM-yyyy' }}
</p>


<p>
  URL: {{ livro.url }}
</p>

<p>
  JSON: {{ livro | json }}
</p>

add script on camel-case.pipe.ts
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'camelCase'
})
export class CamelCasePipe implements PipeTransform {

  transform(value: any, args?: any): any {    
    let values = value.split(' ');
    let result  = '';
    for(let v of values){
      result += this.capitalize(v) + ' ';
    }
    return result;
  }

  capitalize(value: string){
    return value.substr(0,1).toString().toUpperCase() + value.substr(1).toString().toLowerCase()
  }

}


app.module.ts
import { LivroComponent } from './livro/livro.component';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';

import { CursosModule } from './cursos/cursos.module';
import { CriarCursosModule } from './criar-cursos/criar-cursos.module';
import { CamelCasePipe } from './livro/camel-case.pipe';


//import { ReceberCursoCriadoComponent } from './receber-curso-criado/receber-curso-criado.component';

@NgModule({ 
  declarations: [
    AppComponent,
    LivroComponent,
    CamelCasePipe
    //ReceberCursoCriadoComponent //disable this line
  ],
  imports: [
    BrowserModule,
    CursosModule,
    CriarCursosModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

------------------------------//--------------------------------------//-----------------------------

How to setup the standard language on the pipes?

ng g s settings 
add script on settings.service.ts

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class SettingsService {

  constructor() { }

  getLocate(){
    return 'pt';
  }
}

add script on app.module.ts
import { SettingsService } from './settings.service';
import { LivroComponent } from './livro/livro.component';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, LOCALE_ID } from '@angular/core'; //ADD LOCALE_ID here

import localePtBR from '@angular/common/locales/pt'; //ADD this line for Portguese from Brazil

import { AppComponent } from './app.component';

import { CursosModule } from './cursos/cursos.module';
import { CriarCursosModule } from './criar-cursos/criar-cursos.module';
import { CamelCasePipe } from './livro/camel-case.pipe';
import { registerLocaleData } from '@angular/common';

//import { ReceberCursoCriadoComponent } from './receber-curso-criado/receber-curso-criado.component';

registerLocaleData(localePtBR); //ADD this line

@NgModule({ 
  declarations: [
    AppComponent,
    LivroComponent,
    CamelCasePipe
  ],
  imports: [
    BrowserModule,
    CursosModule,
    CriarCursosModule
  ],
  providers: [ //ADD All this providers section
    SettingsService,
    {
      provide: LOCALE_ID,
      deps: [SettingsService],
      useFactory: (settingsService) => settingsService.getLocate()
    }
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

After all that the book price will show as Preco: R$ 23,53 with comma instead of . like in english


------------------------------//--------------------------------------//-----------------------------
How to create a CanDeactive generic interface


By |2020-08-26T23:29:07-06:00August 26th, 2020|Web Developer|Comments Off on Angular – Tutorial

About the Author: