adding HttpInterceptors...

This commit is contained in:
Maria Teresa Paratore 2023-11-21 18:50:56 +01:00
parent 31a74a259a
commit 5988c79723
12 changed files with 168 additions and 87 deletions

View File

@ -1,6 +1,6 @@
import { NgModule, LOCALE_ID, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { NgModule, LOCALE_ID, CUSTOM_ELEMENTS_SCHEMA, importProvidersFrom } from '@angular/core';
import { registerLocaleData } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';
import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
import locale from '@angular/common/locales/en';
import { BrowserModule, Title } from '@angular/platform-browser';
import { ServiceWorkerModule } from '@angular/service-worker';
@ -18,7 +18,6 @@ import { HomeModule} from './home/home.module';
// jhipster-needle-angular-add-module-import JHipster will add new module here
import { NgbDateDayjsAdapter } from './config/datepicker-adapter';
import { fontAwesomeIcons } from './config/font-awesome-icons';
import { httpInterceptorProviders } from 'app/core/interceptor/index';
import { MainComponent } from './layouts/main/main.component';
import { NavbarComponent } from './layouts/navbar/navbar.component';
import { FooterComponent } from './layouts/footer/footer.component';
@ -29,6 +28,7 @@ import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { RawjsonPaneComponent } from './rawjson-pane/rawjson-pane.component';
import { ClipboardModule } from '@angular/cdk/clipboard';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { SpinnercontrolInterceptor } from './shared/spinnercontrol.interceptor';
@NgModule({
imports: [
@ -51,6 +51,7 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
Title,
{ provide: LOCALE_ID, useValue: 'en' },
{ provide: NgbDateAdapter, useClass: NgbDateDayjsAdapter },
{provide:HTTP_INTERCEPTORS,useClass:SpinnercontrolInterceptor, multi: true}
],
declarations: [MainComponent, NavbarComponent, ErrorComponent, PageRibbonComponent, ActiveMenuDirective, FooterComponent],
bootstrap: [MainComponent],

View File

@ -8,9 +8,7 @@ export function instanceOfContext(context: any): boolean{
const res = !!context // truthy
&& typeof context !== 'string' // Not just string input in the autocomplete
&& 'name' in context; // Has some qualifying property of context type
console.debug("--- In instanceOfContext: ");
console.debug(res);
console.debug("---");
return res;
}

View File

@ -1,10 +1,7 @@
<div class="row" >
<div *ngIf="ctxLoaderService.isLoading|async" class="loader-container">
<mat-progress-bar mode="indeterminate" ></mat-progress-bar>
<div *ngIf="loading" class="loader-container">
<mat-spinner mode="indeterminate" style="top: 50%; left: 50%;"></mat-spinner>
</div>
<div class="d-flex flex-row py-4">
<div id="btn-group" class="col-md-3 mt-3">
<button mat-raised-button color="primary"><mat-icon>source</mat-icon> <span>File</span></button>
@ -18,6 +15,8 @@
<jhi-rsc-tree (resourceTypeEm)="buildTableData($event)"></jhi-rsc-tree>
</div>
</div>
</div>
<div class="col-md-9">

View File

@ -23,20 +23,11 @@ Main page styles
}
.loader-container{
position: fixed;
position: absolute;
height: 100%;
width: 100%;
background: black;
opacity: 0.3;
z-index: 99;
}
/*
.loading-container {
display: flex;
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: rgba(0,0,0,0.7);
z-index: 5;
}
*/

View File

@ -12,17 +12,18 @@ import { AccountService } from 'app/core/auth/account.service';
import { Account } from 'app/core/auth/account.model';
import { AbstractControl, FormBuilder, FormControl, FormGroup, ValidationErrors, ValidatorFn, Validators } from '@angular/forms';
import { Clipboard } from '@angular/cdk/clipboard'
import { Observable, delay, map, startWith } from 'rxjs';
import { BehaviorSubject, Observable, delay, map, startWith } from 'rxjs';
import { ContextsLoaderService } from 'app/services/contexts-loader.service';
import { IContextNode } from 'app/services/i-context-node';
import { AutofillValidator, instanceOfContext } from './autofill-validator';
import { SpinnerLoadingService } from 'app/services/spinner-loading.service';
@Component({
selector: 'jhi-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss'],
providers: [ContextsLoaderService],
providers: [ContextsLoaderService, SpinnerLoadingService],
})
export class HomeComponent implements OnInit {
@ -34,13 +35,14 @@ export class HomeComponent implements OnInit {
//public filteredContextsStr: Observable<string[]>| undefined;
chooseContextForm: FormGroup | any;
resType: string;
loading: boolean = false;
loading: boolean = false;
constructor(
private accountService: AccountService,
private loginService: LoginService,
public ctxLoaderService : ContextsLoaderService,
private ctxLoaderService : ContextsLoaderService,
private progressService : SpinnerLoadingService,
private fb: FormBuilder,
private clipboard: Clipboard) {
//initialise on HostingNodes
@ -59,19 +61,22 @@ export class HomeComponent implements OnInit {
}
ngOnInit(): void {
//this.listenToLoading();
//to identify users and their account
this.accountService.identity().subscribe(account => (this.account = account));
this.chooseContextForm = this.fb.group({
namefield: ['', [Validators.required,AutofillValidator]],
uidfield: [''],
});
//TODO: DEBUG HERE
//vedi: https://medium.com/swlh/angular-loading-spinner-using-http-interceptor-63c1bb76517b
//per ora ascolto solo il caricamento dei contesti
this.listenToLoading();
// per la form dei contesti
this.ctxLoaderService.fetchAll().subscribe(res => {
this.allCtxs = res;
});
console.debug("----->val:"+this.chooseContextForm.get('namefield').value);
this.filteredContexts = this.chooseContextForm.get('namefield').valueChanges.pipe(
startWith(''),
map(ctx => (ctx ? this.filterContexts(ctx/*,contextInput*/) : this.allCtxs.slice()))
@ -79,7 +84,19 @@ export class HomeComponent implements OnInit {
}
/**
* Listen to the loadingSub property in the LoadingService class. This drives the
* display of the loading spinner.
*/
listenToLoading(): void {
this.progressService.getState()
.subscribe((loading) => {
this.loading = loading;
console.debug("**********this.loading..."+this.loading);
});
}
//mettere ANY come tipo dell'argomento per evitare errore TypeScript nella map!!
filterContexts(/*ctx: IContextNode,*/ item: any): IContextNode[] {

View File

@ -15,8 +15,6 @@ import { TableScreenModule } from 'app/table-screen/table-screen.module';
import { TableScreenEsModule } from 'app/table-screen-es/table-screen-es.module';
import { AsyncPipe, NgSwitchCase, NgSwitchDefault } from '@angular/common';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { InterceptorService } from 'app/services/interceptor.service';
@NgModule({
imports: [SharedModule,
@ -36,8 +34,5 @@ import { InterceptorService } from 'app/services/interceptor.service';
NgSwitchDefault],
declarations: [HomeComponent],
schemas:[CUSTOM_ELEMENTS_SCHEMA],
providers:[
{provide:HTTP_INTERCEPTORS,useClass:InterceptorService, multi: true}
]
})
export class HomeModule {}

View File

@ -1,7 +1,8 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable no-console */
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { BehaviorSubject, Observable, map, tap } from 'rxjs';
import { Observable } from 'rxjs';
import { appProperties } from 'app/config/app-properties';
import { IContextNode } from './i-context-node';
@ -9,17 +10,17 @@ import { IContextNode } from './i-context-node';
providedIn: 'root',
})
export class ContextsLoaderService {
public isLoading: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' }),
};
constructor(private http: HttpClient) {}
fetchAll(): Observable<IContextNode[]> {
return this.http.get<IContextNode[]>(appProperties.BASEURL_API + 'is/allcontexts');
return this.http.get<IContextNode[]>(appProperties.BASEURL_API + 'is/allcontexts');
}
}

View File

@ -1,22 +0,0 @@
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { ContextsLoaderService } from './contexts-loader.service';
import { Observable, finalize } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class InterceptorService implements HttpInterceptor{
constructor(public ctxLoaderServ : ContextsLoaderService) { }
intercept(req: HttpRequest<any>, next:HttpHandler): Observable<HttpEvent<any>>{
this.ctxLoaderServ.isLoading.next(true);
return next.handle(req).pipe(
finalize(
()=>{
this.ctxLoaderServ.isLoading.next(false);
})
);
}
}

View File

@ -1,20 +0,0 @@
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';
import { IContextNode } from './i-context-node';
@Injectable({
providedIn: 'root',
})
export class MockCtxloaderService {
httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' }),
};
constructor(private http: HttpClient) {}
getData(): Observable<IContextNode[]> {
//TODO: pipe per gestione errori
return this.http.get<IContextNode[]>('http://localhost:3002/is/allcontexttree');
}
}

View File

@ -1,6 +1,6 @@
/* eslint-disable no-console */
import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';
import { BehaviorSubject, Observable, Subject } from 'rxjs';
import { appProperties } from 'app/config/app-properties';
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import { IHostingNode } from './i-hosting-node';
@ -11,12 +11,19 @@ import { IEService } from './i-e-service';
})
export class ResourcesImplService {
public isLoading: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
//public isLoading: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' }),
};
private loading: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
constructor(private http: HttpClient) { }
public isLoading():Observable<any>{
return this.loading;
}
//TODO: qui va messo parametro per paginazione
fetchResourceImpls(ctx:string, type:string): Observable<any[]> {

View File

@ -0,0 +1,35 @@
/* eslint-disable @typescript-eslint/explicit-function-return-type */
/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */
/* eslint-disable @typescript-eslint/no-empty-function */
import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class SpinnerLoadingService {
private state: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(true);
constructor() { }
getState():Observable<boolean>{
return this.state.asObservable();
};
setState(newState : boolean) : void{
this.state.next(newState);
};
}
/*
*/

View File

@ -0,0 +1,79 @@
/* eslint-disable @typescript-eslint/explicit-function-return-type */
/* eslint-disable no-console */
import { Injectable } from '@angular/core';
import {
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor,
HttpResponse
} from '@angular/common/http';
import { Observable, finalize, tap } from 'rxjs';
//import { SpinnerLoadingService } from 'app/services/spinner-loading.service';
import { ContextsLoaderService } from 'app/services/contexts-loader.service';
import { SpinnerLoadingService } from 'app/services/spinner-loading.service';
@Injectable()
export class SpinnercontrolInterceptor implements HttpInterceptor {
/*
Like intercept(), the handle() method transforms an HTTP request into an Observable
of HttpEvents which ultimately include the server's response.
The intercept() method could inspect that observable and alter it before returning
it to the caller.
*/
private myService : SpinnerLoadingService;
constructor(private spinnerLoaderServ: SpinnerLoadingService) {
this.myService = spinnerLoaderServ;
}
intercept(req: HttpRequest<any>, next: HttpHandler) {
const started = Date.now();
let ok: string;
// extend server response observable with logging
return next.handle(req)
.pipe(
tap({
// Succeeds when there is a response; ignore other events
next: (event) => (ok = event instanceof HttpResponse ? 'succeeded' : ''),
// Operation failed; error is an HttpErrorResponse
error: (_error) => (ok = 'failed')
}),
// Log when response observable either completes or errors
finalize(() => {
const elapsed = Date.now() - started;
const msg = `${req.method} "${req.urlWithParams}"
${ok} in ${elapsed} ms.`;
console.debug("***** MSG INIZIO ******");
console.debug(msg);
console.debug("***** MSG FINE ******");
this.spinnerLoaderServ.setState(false);
})
);
}
/*
intercept(
request: HttpRequest<any>,next: HttpHandler): Observable<HttpEvent<Response>> {
console.log('********Outgoing HTTP request', request);
if(request.url.includes('resourcetypes')){
return next.handle(request).pipe(
tap((event: HttpEvent<any>) => {
console.log('*******Incoming HTTP response', event);
this.spinnerLoaderServ.setState(false);
})
);
}else{
return new Observable<HttpEvent<any>>();
}
}
*/
}