angular - ¿Cómo mostrar un spinner durante una solicitud?
Hay una aplicación que envía solicitudes http. Un servicio especial almacena el estado del spinner. Para hacer esto utiliza BeahivoirSubject. El interceptor establece el estado del spinner en verdadero antes de cualquier solicitud http. Cuando la solicitud http finaliza, el interceptor establece el estado del spinner en falso.
Sin embargo, el spinner no se muestra en absoluto. Este es el problema. Por favor, ayude a mostrar un spinner durante una solicitud HTTP.
Agrego deliberadamente un retraso artificial de 2000 ms a cada solicitud http usando las capacidades de RXJS.
DEMOSTRACIÓN EN VIVO
Código del interceptor:
@Injectable()
export class MyInterceptor implements HttpInterceptor {
constructor(private globalService: GlobalService) {}
intercept(
request: HttpRequest<unknown>,
next: HttpHandler
): Observable<HttpEvent<unknown>> {
request = request.clone({
setHeaders: { Authorization: `Bearer 123` }
});
this.globalService.setSpinnerState(true);
return next
.handle(request)
.pipe(finalize(() => this.globalService.setSpinnerState(false)));
}
}
Solicitar código de servicio:
@Injectable({
providedIn: "root"
})
export class ApiService {
constructor(private http: HttpClient) {}
getData() {
console.log("start request");
return this.http
.get("https://jsonplaceholder.typicode.com/todos/1")
.pipe(delay(2000))
.subscribe((res: any) => {
console.log(res);
console.log("end request");
});
}
}
Código del servicio de spinner:
@Injectable({
providedIn: "root"
})
export class GlobalService {
private isShowSpinner = new BehaviorSubject(false);
constructor() {}
spinner() {
return this.isShowSpinner.asObservable();
}
setSpinnerState(state: boolean) {
return this.isShowSpinner.next(state);
}
}
Código del componente:
@Component({
selector: "my-app",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
isShowSpinner: boolean;
constructor(
private apiService: ApiService,
private globalService: GlobalService
) {
this.apiService.getData();
this.globalService.spinner().subscribe((state: boolean) => {
this.isShowSpinner = state;
});
}
}
Respuesta #1
Tu enfoque es generalmente correcto. En el ejemplo que proporcionaste, pude ver el spinner por un breve período de tiempo. Sin embargo, la forma en que implementaste el retraso artificial para una llamada API es incorrecta. next.handle solo espera a que la llamada HTTP se complete, así que tan pronto como sucedió, la función setSpinnerState se ha llamado con false como parámetro. Si quieres ver el retraso con fines de prueba, deberías poner el retraso en el interceptor de esta manera
return next.handle(request).pipe(
delay(2000),
finalize(() => this.globalService.setSpinnerState(false))
);
y por supuesto elimínalo del api.service.
