Servicios

Primero vamos a crear nuestras variables environment para conectar al api rest nos vamos al directorio environments y en el archivo environment.ts esto es en la parte de desarrollo.
 
               
         export const environment = {
  production: false,
  urlHost:'http://localhost:8080/',
  urlApi:'http://localhost:8080/api/v1'
};   
            
            
      
   

A continuación vamos a crear nuestro servicio con el siguiente comando
 
               
    ng g s services/login
  
   
   

java project
En la carpeta services creamos archivo llamado loginRequest.ts que va hacer una interface
 
              
  export interface LoginRequest {
    username:string,
    password:string
}
   
   

En la carpeta services creamos el archivo llamado autresponse.ts que va hacer una interface
 
              
  export interface Autresponse{
    token:string;
    username:string;
}
  
  
    
   

En el archivo login.service.ts escribimos lo siguiente
 
              
  import { Injectable } from '@angular/core';
import { LoginRequest } from './loginRequest';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Observable, catchError, throwError,BehaviorSubject, tap, map } from 'rxjs';
import { Administrador } from './administrador';
import { Autresponse } from './autresponse';
import { environment } from 'src/environments/environment';

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

  currentAdministradorLoginOn:BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
  currentAdministradorData:BehaviorSubject<String>=new BehaviorSubject<String>("");
  currentAdmin:BehaviorSubject<Autresponse>=new BehaviorSubject<Autresponse>({token:'',username:''});
  constructor(private http:HttpClient) { 
    this.currentAdministradorLoginOn=new BehaviorSubject<boolean>(sessionStorage.getItem("token")!=null);
    this.currentAdministradorData=new BehaviorSubject<String>(sessionStorage.getItem("token") || "");
    this.currentAdmin=new BehaviorSubject<Autresponse>({token:'',username:''})
  }


  login(credentials:LoginRequest):Observable<Autresponse>{

    return this.http.post<Autresponse>(environment.urlHost+"auth/login",credentials).pipe(
      tap((userData)=>{
        sessionStorage.setItem("token",userData.token);
        this.currentAdmin.next(userData);
        this.currentAdministradorData.next(userData.token);
        this.currentAdministradorLoginOn.next(true);
      }),
     
      catchError(this.handleError)
    )

  }
   
  private handleError(error:HttpErrorResponse){
    if(error.status===0){
      console.error('Se ha producio un error ', error.error);
    }
    else{
      console.error('Backend retornó el código de estado ', error);
    }
    return throwError(()=> new Error('Algo falló. Por favor intente nuevamente.'));
  }


  logout():void{
    sessionStorage.removeItem("token");
    this.currentAdministradorLoginOn.next(false);
  }




  get userData():Observable<Autresponse>{
    return this.currentAdmin.asObservable();
  }  
  
  get userLoginOn():Observable<boolean>{
    return this.currentAdministradorLoginOn.asObservable();
  }


}
  
  
  
  
  
    
   

creamos el servicio administrador
 
               
    
    ng g s services/administrador
  
   
   

java project
En la carpeta services creamos archivo llamado administrador.ts que va hacer una interface
 
               
export interface Administrador{
    idAdmin:number;
    nombre:string;
    apellidoPaterno:string;
    apellidoMaterno?:string;
    correo:string;
    celular:string;
    rol:string;
}
  
   

En el archivo administrador.service.ts escribimos lo siguiente
 
               
 import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, catchError,throwError } from 'rxjs';
import { Administrador } from './administrador';
import { environment } from 'src/environments/environment';

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

  constructor(private http:HttpClient) {}


   getAdministrador(email:string):Observable<Administrador>
   {

    return this.http.get<Administrador>(environment.urlApi+"/admin/"+email).pipe(
      catchError(this.handleError)
    )
   }

   private handleError(error:HttpErrorResponse){
    if(error.status===0){
      console.error('Se ha producio un error ', error.error);
    }
    else{
      console.error('Backend retornó el código de estado ', error.status, error.error);
    }
    return throwError(()=> new Error('Algo falló. Por favor intente nuevamente.'));
  }


}
 
 
  
    
   

Invocando los Servicios

Para mandar a llamar nuestro servicio que creamos tenemos que modificar los siguinetes archivos.
Abrimos el archivo login.component.ts y lo dejamos de la siguiente forma
 
               
  import { Component, OnInit } from '@angular/core';
import {AbstractControl, FormBuilder,Validators} from '@angular/forms';
import { Router } from '@angular/router';
import { LoginService } from 'src/app/services/login.service';
import { LoginRequest } from 'src/app/services/loginRequest';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
  loginError:string="";
  loginForm=this.formBuilder.group({
    username:['',[Validators.required,Validators.email]],
    password:['',Validators.required],
  }

  )

  


  constructor(private formBuilder:FormBuilder,private router:Router,
    private loginService:LoginService) { }

  ngOnInit(): void {
  }

  get f(): { [key: string]: AbstractControl } {
    return this.loginForm.controls;
  }
  

 login(){
  if(this.loginForm.valid){
    this.loginService.login(this.loginForm.value as LoginRequest).subscribe({
      next:(userData)=>{
        console.log(userData);
      },
      error:(errorData)=>{
        console.error(errorData);
        this.loginError=errorData;
      },
      complete:()=>{
        console.info("Login completo");
        this.router.navigateByUrl('/inicio');
        this.loginForm.reset();
      }
    })
    
  }else{
     this.loginForm.markAllAsTouched();
    //alert("Ingresar los datos correctamente");
  }
 }

  

}
  
  
    
   

En el código anterior se modifico la variable username por lo tanto tenemos que modificar el archivo login.component.html
 
               
  <mat-card class="example-card">
    <mat-card-title>Introduce tus datos</mat-card-title>
    <mat-card-content>
        <form [formGroup]="loginForm">
            <p class="text-danger">{{loginError}}</p>
            <p>
                <mat-form-field>
                    <input type="text" formControlName="username" matInput placeholder="Email" formControlName="username">
                </mat-form-field>
            </p>

            <div *ngIf="f['username'].invalid && (f['username'].dirty || f['username'].touched)" class="text-danger">
                <div *ngIf="f['username'].errors?.['required']">
                    El Email es requerido.
                </div>
                <div *ngIf="f['username'].errors?.['email']">
                    El Email debe tener un formato válido.
                </div>
            </div>

            <p>
                <mat-form-field>
                    <input type="password" formControlName="password" matInput placeholder="Password" formControlName="password">
                </mat-form-field>
            </p>
            <div *ngIf="f['password'].invalid && (f['password'].dirty || f['password'].touched)" class="text-danger">
                <div *ngIf="f['password'].errors?.['required']">
                    El Password es requerido.
                </div>
            </div>

            <div class="button">
                <button type="submit" (click)="login()" mat-button>Acceder</button>
            </div>

        </form>
    </mat-card-content>
</mat-card>
  
  
  
    
   

Nos vamos al archivo dashboard.component.ts lo dejamos de la siguiente manera
 
               
  
  import { Component, OnDestroy, OnInit } from '@angular/core';
import { Administrador } from 'src/app/services/administrador';
import { AdministradorService } from 'src/app/services/administrador.service';
import { Autresponse } from 'src/app/services/autresponse';
import { LoginService } from 'src/app/services/login.service';

@Component({
  selector: 'app-dashboard',
  templateUrl: './dashboard.component.html',
  styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit {
  errorMessage:String="";
  userLoginOn:boolean=false;
  userData?:Autresponse;
  admin?:Administrador;

  constructor(private loginService:LoginService,private adminService:AdministradorService) { }

  

  ngOnInit(): void {

    this.loginService.currentAdministradorLoginOn.subscribe(
      {
        next:(userLoginOn)=>{
          this.userLoginOn=userLoginOn;
        }
      }
    );

    this.loginService.currentAdmin.subscribe(
      {
        next:(userData)=>{
          this.userData=userData;
          console.log("Probando:"+this.userData.username);
          this.adminService.getAdministrador(userData.username).subscribe({
            next: (adminData) => {
              this.admin=adminData;
             
            },
            error: (errorData) => {
              this.errorMessage=errorData
            },
            complete: () => {
              console.info("User Data ok");
            }
          })
        }
      }
    );


    






  }

}
  
  
    
   

El archivo dashboard.component.html queda de la siguiente forma
 
               
  <app-menu></app-menu>


<mat-card class="example-card">
    <mat-card-title>
        <p *ngIf="!userLoginOn">Usuario NO autenticado</p>
        <p *ngIf="userLoginOn">Usuario Autenticado</p>
    </mat-card-title>
    <mat-card-content>
        <div *ngIf="userLoginOn">
            <p>Nombre: {{admin?.nombre}}</p>
            <p>Apellidos: {{admin?.apellidoPaterno}} {{admin?.apellidoMaterno}}</p>
            <p>Email: {{admin?.correo}}</p>
        </div>
    </mat-card-content>
</mat-card>
    
   

Modifica el archivo menu.component.ts
 
               
  import { Component, OnDestroy, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { LoginService } from 'src/app/services/login.service';

@Component({
  selector: 'app-menu',
  templateUrl: './menu.component.html',
  styleUrls: ['./menu.component.css']
})
export class MenuComponent implements OnInit {
   
  userLoginOn:boolean=false;


  constructor(private loginService:LoginService, private router:Router) { }

 
  ngOnInit(): void {
    this.loginService.currentAdministradorLoginOn.subscribe(
      {
        next:(userLoginOn)=>{
          this.userLoginOn=userLoginOn;
        }
      }
    )
  }

  logout()
  {
    this.loginService.logout();
    this.router.navigate(['/inicio'])
  }




}
  
  
     
   

El archivo menu.component.html queda de la siguiente forma
 
               
  <button mat-button [matMenuTriggerFor]="inicioMenu">Inicio</button>
<mat-menu #inicioMenu="matMenu" yPosition="above">
    <button *ngIf="!userLoginOn" mat-menu-item routerLink="/login">Iniciar Sesión</button>
    <button *ngIf="userLoginOn" (click)="logout()" mat-menu-item routerLink="/inicio">Cerrar Sesión</button>
</mat-menu>
  
  
     
   

Probando

No hay que olvidar que para que funcione esto hay que correr el api rest y posteriormente nuestro proyecto en angular.


Registrar Administrador

Primero vamos a crear un servicio para invocar la validación que si eres adminstrador con pefil ADMIN puedes ver el formulario para agregar administradores y si eres Administrador USER no tienes permiso.
Creamos el servicio llamado helper con el siguiente comando
 
               
       
       ng c s services/helper
       
        
        

En el archivo helper.service.ts escribimos lo siguiente:
 
               
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

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

  private rolAdminOn = new BehaviorSubject(false);
  public customRolOn = this.rolAdminOn.asObservable();

  constructor() { }

  public validaAdmin(rolAdmin:boolean){
     
     this.rolAdminOn.next(rolAdmin);    
    


  }

}
       
       
       
        
  
       
       
       
        
        

Modificamos el archivo dashboard.component.ts para realizar la validación ya de aqui tomamos el datos del rol
 
               
       
       import { Component, OnDestroy, OnInit } from '@angular/core';
import { Administrador } from 'src/app/services/administrador';
import { AdministradorService } from 'src/app/services/administrador.service';
import { Autresponse } from 'src/app/services/autresponse';
import { HelperService } from 'src/app/services/helper.service';
import { LoginService } from 'src/app/services/login.service';

@Component({
  selector: 'app-dashboard',
  templateUrl: './dashboard.component.html',
  styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit {
  errorMessage:String="";
  userLoginOn:boolean=false;
  userData?:Autresponse;
  admin?:Administrador;
  userAdminOn=false;
  constructor(private loginService:LoginService,private adminService:AdministradorService,
    private helper: HelperService
  ) { }

  

  ngOnInit(): void {

    this.loginService.currentAdministradorLoginOn.subscribe(
      {
        next:(userLoginOn)=>{
          this.userLoginOn=userLoginOn;
        }
      }
    );

    this.loginService.currentAdmin.subscribe(
      {
        next:(userData)=>{
          this.userData=userData;
          console.log("Probando:"+this.userData.username);
          this.adminService.getAdministrador(userData.username).subscribe({
            next: (adminData) => {
              this.admin=adminData;
              console.log(adminData.rol);
              if( adminData.rol == 'ADMIN'){
                let adminOn=true; 
                this.helper.customRolOn.subscribe(adminOn => this.userAdminOn = adminOn); 
                this.helper.validaAdmin(adminOn);
               }else{
                let adminOn=false; 
                this.helper.customRolOn.subscribe(adminOn => this.userAdminOn = adminOn); 
                this.helper.validaAdmin(adminOn);
               }


            },
            error: (errorData) => {
              this.errorMessage=errorData
            },
            complete: () => {
              console.info("User Data ok");
            }
          })
        }
      }
    );


   
       


  }




}
       
       
       
       
       
       
       
       
           
        

Modificamos el archivo administrador.service.ts en el cual generamos el servicio crearAdminstrador
 
               
       import { HttpClient, HttpErrorResponse, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, catchError,throwError } from 'rxjs';
import { Administrador } from './administrador';
import { environment } from 'src/environments/environment';

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

  private httpHeaders = new HttpHeaders({'Content-Type':'application/json'})

  constructor(private http:HttpClient) {}


   getAdministrador(email:string):Observable<Administrador>
   {

    return this.http.get<Administrador>(environment.urlApi+"/admin/"+email).pipe(
      catchError(this.handleError)
    )
   }

   crearAdministrador(admin:Administrador):Observable<Administrador>
   {

     return this.http.post<Administrador>(environment.urlApi+"/admin",admin).pipe(
      catchError(this.handleError)
     )
   }





   private handleError(error:HttpErrorResponse){
    if(error.status===0){
      console.error('Se ha producio un error ', error.error);
    }
    else{
      console.error('Backend retornó el código de estado ', error.status, error.error);
    }
    return throwError(()=> new Error('Algo falló. Por favor intente nuevamente.'));
  }


}
       
       
         
        

Lo que sigue es que vamos a crear un dialogo para que cuando insertemos nuestro administador nos avise.Creamos el componente createuserdialog con el siguiente comando:
 
               
  
  ng g c dashboard/createuserdialog
  
     
        

En el archivo createuserdialog.component.html escribimos lo siguiente:
 
               
  <h1 mat-dialog-title>Administrador Insertado</h1>
<div mat-dialog-content>Administrador fue insertado.</div>
<div mat-dialog-actions>
    <button mat-button mat-dialog-close>Close</button>
</div>
  
  
    
        

En el archivo app.module.ts agregamos el MatDialogModule
 
               
  import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HeaderComponent } from './shared/header/header.component';
import { FooterComponent } from './shared/footer/footer.component';
import { LoginComponent } from './pages/login/login.component';
import { DashboardComponent } from './pages/dashboard/dashboard.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import {MatMenuModule} from '@angular/material/menu';
import {MatButtonModule} from '@angular/material/button';
import {MatCardModule} from '@angular/material/card';
import { MenuComponent } from './shared/menu/menu.component';
import { MatInputModule} from '@angular/material/input';
import { ReactiveFormsModule } from '@angular/forms';
import {HTTP_INTERCEPTORS, HttpClientModule} from '@angular/common/http';
import { FormadminComponent } from './dashboard/formadmin/formadmin.component';
import { CreateuserdialogComponent } from './dashboard/createuserdialog/createuserdialog.component';
import {MatDialogModule} from '@angular/material/dialog';


@NgModule({
  declarations: [
    AppComponent,
    HeaderComponent,
    FooterComponent,
    LoginComponent,
    DashboardComponent,
    MenuComponent,
    FormadminComponent,
    CreateuserdialogComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    MatMenuModule,
    MatButtonModule,
    MatCardModule,
    MatInputModule,
    ReactiveFormsModule,
    HttpClientModule,
    MatDialogModule
  ],
  providers: [
   
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }
  
  
  
  
  
     
        

Ahora vamos a crear el componente para nuestro formulario que va craer el administrador lo vamos a llamar formadmin
 
               
  
  ng g c dashboard/formadmin
  
     
        

En el archivo formadmin.component.ts escribimos lo siguiente:
 
               
  
  import { Component, OnInit } from '@angular/core';
import {AbstractControl, FormBuilder,Validators} from '@angular/forms';
import { Router } from '@angular/router';
import {MatDialog} from '@angular/material/dialog';
import { CreateuserdialogComponent } from '../createuserdialog/createuserdialog.component';
import { AdministradorService } from 'src/app/services/administrador.service';
import { Administrador } from 'src/app/services/administrador';
import { HelperService } from 'src/app/services/helper.service';

@Component({
  selector: 'app-formadmin',
  templateUrl: './formadmin.component.html',
  styleUrls: ['./formadmin.component.css']
})
export class FormadminComponent implements OnInit {
  public userAdminOn:boolean=false;
  adminError:string="";
  adminForm=this.formBuilder.group({
    nombre:['',Validators.required],
    apellidoPaterno:['',Validators.required],
    apellidoMaterno:'',
    correo:['',[Validators.required,Validators.email]],
    celular:['',[Validators.required,Validators.pattern("^[0-9]*$")]],
    password:['',Validators.required],
    rol:''
  }

  )

  constructor(private formBuilder:FormBuilder,public dialog: MatDialog,
    private adminService:AdministradorService,private router:Router,
    private helper: HelperService
  ) { }

  ngOnInit(): void {
    
    this.helper.customRolOn.subscribe(
      {
        next:(userAdminOn)=>{
          this.userAdminOn=userAdminOn;
          console.log("El dato es igual:"+this.userAdminOn);
        }
      }
    );
    
  }

  get f(): { [key: string]: AbstractControl } {
    return this.adminForm.controls;
  }

  insertarAdmin(){
    if(this.adminForm.valid){
      
      this.adminService.crearAdministrador(this.adminForm.value as Administrador).subscribe({
        next:(userData)=>{
          console.log(userData);
        },
        error:(errorData)=>{
          console.error(errorData);
          this.adminError=errorData;
        },
        complete:()=>{
          this.dialog.open(CreateuserdialogComponent);  
          this.router.navigateByUrl('/inicio');
          this.adminForm.reset();
        }
      })
      
          
    }
    else{
      this.adminForm.markAllAsTouched();
     //alert("Ingresar los datos correctamente");
   }
  }

}
  
  
  
  
  
   
        

En el archivo formadmin.component.html escribimos lo siguiente:
 
               
  <app-menu></app-menu>




<mat-card class="example-card">
    <div *ngIf="userAdminOn">

        <mat-card-content>
            <mat-card-title>Crear Administrador</mat-card-title>
            <form [formGroup]="adminForm">
                <p class="text-danger">{{adminError}}</p>

                <p>
                    <mat-form-field>
                        <input type="text" formControlName="nombre" matInput placeholder="Introducir Nombre">
                    </mat-form-field>
                </p>
                <div *ngIf="f['nombre'].invalid && (f['nombre'].dirty || f['nombre'].touched)" class="text-danger">
                    <div *ngIf="f['nombre'].errors?.['required']">
                        El nombre es requerido.
                    </div>
                </div>
                <p>
                    <mat-form-field>
                        <input type="text" formControlName="apellidoPaterno" matInput placeholder="Introducir Apellido Paterno">
                    </mat-form-field>
                </p>
                <div *ngIf="f['apellidoPaterno'].invalid && (f['apellidoPaterno'].dirty || f['apellidoPaterno'].touched)" class="text-danger">
                    <div *ngIf="f['apellidoPaterno'].errors?.['required']">
                        El apellido paterno es requerido.
                    </div>
                </div>
                <p>
                    <mat-form-field>
                        <input type="text" formControlName="apellidoMaterno" matInput placeholder="Introducir Apellido Materno">
                    </mat-form-field>
                </p>

                <p>
                    <mat-form-field>
                        <input type="text" formControlName="correo" matInput placeholder="Introducir email">
                    </mat-form-field>
                </p>

                <div *ngIf="f['correo'].invalid && (f['correo'].dirty || f['correo'].touched)" class="text-danger">
                    <div *ngIf="f['correo'].errors?.['required']">
                        El Email es requerido.
                    </div>
                    <div *ngIf="f['correo'].errors?.['email']">
                        El Email debe tener un formato válido.
                    </div>
                </div>

                <p>
                    <mat-form-field>
                        <input type="text" formControlName="celular" matInput placeholder="Introducir celular">
                    </mat-form-field>
                </p>

                <div *ngIf="f['celular'].invalid && (f['celular'].dirty || f['celular'].touched)" class="text-danger">
                    <div *ngIf="f['celular'].errors?.['required']">
                        El celular es requerido.
                    </div>
                    <div *ngIf="f['celular'].errors?.['pattern']">
                        Meter solo números.
                    </div>
                </div>

                <p>
                    <mat-form-field>
                        <input type="password" formControlName="password" matInput placeholder="Introducir Password" autocomplete="on">
                    </mat-form-field>
                </p>
                <div *ngIf="f['password'].invalid && (f['password'].dirty || f['password'].touched)" class="text-danger">
                    <div *ngIf="f['password'].errors?.['required']">
                        El Password es requerido.
                    </div>
                </div>


                <mat-form-field appearance="fill">
                    <mat-label>Perfil Administrador</mat-label>
                    <select matNativeControl required formControlName="rol">
                    <option value="USER" selected>Usuario</option>
                  <option value="ADMIN">Administrador</option>
                  
                </select>
                </mat-form-field>



                <div class="button">
                    <button type="submit" (click)="insertarAdmin()" mat-raised-button color="primary">Registrar Administrador</button>
                </div>








            </form>


        </mat-card-content>

    </div>
    <div *ngIf="!userAdminOn">
        <mat-card-content>
            <mat-card-title>No tienes permiso para agregar administradores</mat-card-title>
        </mat-card-content>
    </div>
</mat-card>
   
        

Vamos a crear la funcionalidad de crear administrador, primero vamos a crear la ruta y modificando el archivo app-routing.module.ts
 
               
            
          import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { DashboardComponent } from './pages/dashboard/dashboard.component';
import { LoginComponent } from './pages/login/login.component';
import { FormadminComponent } from './dashboard/formadmin/formadmin.component';

const routes: Routes = [
   
  {path:'',redirectTo:'/inicio', pathMatch:'full'},
  {path:'inicio',component:DashboardComponent},
  {path:'login',component:LoginComponent},
  {path:'crearAdmin',component:FormadminComponent} 

];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }
          
          
          
            
            
     
   

Lo que sigue es modificar el menú para invocar la funcionalidad modifcamos el archivo menu.component.html
 
                       
            <button mat-button [matMenuTriggerFor]="inicioMenu">Inicio</button>
<mat-menu #inicioMenu="matMenu" yPosition="above">
    <button *ngIf="!userLoginOn" mat-menu-item routerLink="/login">Iniciar Sesión</button>
    <button *ngIf="userLoginOn" mat-menu-item routerLink="/crearAdmin">Crear Administrador</button>
    <button *ngIf="userLoginOn" (click)="logout()" mat-menu-item routerLink="/inicio">Cerrar Sesión</button>
</mat-menu>
            
     
   

Espero que no me hayga faltado alguna parte código sino reportar a kapo1978@hotmail.com y en breve te contesto.Ahora corremos la aplicación: