[英]How to track Angular HTTP POST call progress
I trying to put a progress bar in my http call but some how i wont be able to make a sync HTTP call request instead its going in async fashion. 我试图在我的http调用中放入一个进度条,但有些我怎么能够以异步方式进行同步HTTP调用请求。
below is function for making http call 以下是进行http调用的功能
public authenticationt2cHTTP(email, password) {
console.log("authenticationt2cHTTP WITH HEADERS");
const body = new HttpParams()
.set('email', email)
.set('password', password);
const req = new HttpRequest('POST', 'http://192.168.0.135:8080/rest/auth/login', body, {
reportProgress: true,
headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded')
});
this.http.request(req).subscribe(event => {
// Via this API, you get access to the raw event stream.
// Look for upload progress events.
if (event.type === HttpEventType.UploadProgress) {
// This is an upload progress event. Compute and show the % done:
const percentDone = Math.round(100 * event.loaded / event.total);
console.log(`File is ${percentDone}% uploaded.`);
} else if (event instanceof HttpResponse) {
console.log('File is completely uploaded!');
}
});
}
below is code which i am using in my component class for making a call and showload is temp variable for showing/hiding preloader of the page. 下面是我在我的组件类中用于进行调用的代码,showload是用于显示/隐藏页面预加载器的临时变量。
this.showLoader = false;
var k = this.myhttpService.authenticationt2c(this.form.get("email").value, this.form.get("password").value);
this.showLoader = true;
I use the following http
service wrapper to get access to different hooks like handleResponse
, beforeRequest
, afterResponse
, onCatch
& onSuccess
. 我用下面的http
服务包装以访问不同的钩子一样handleResponse
, beforeRequest
, afterResponse
, onCatch
和onSuccess
。
The API services should consume the HttpInterceptor
wrapper (which internally triggers the http call and gives access to above mentioned hooks). API服务应该使用HttpInterceptor
包装器(它在内部触发http调用并提供对上述钩子的访问)。
Note how the loader logic is implemented in beforeRequest
& afterResponse
hooks. 注意装载机的逻辑是如何中实现beforeRequest
& afterResponse
挂钩。
import { Injectable } from "@angular/core";
import { XHRBackend, RequestOptions, Request, RequestOptionsArgs, Response, Http, Headers } from "@angular/http";
import { Store } from "@ngrx/store";
import { Observable } from "rxjs/Rx";
import { Observer } from "rxjs/Observer";
import { Response as ApiResponse } from "../../models/base/response.model";
import { ToastModel } from "../../redux/app-reducers";
import { ReducerActions } from "../../redux/reducer-actions";
@Injectable()
export class HttpInterceptor extends Http {
constructor(private _XHRBackend: XHRBackend,
private _RequestOptions: RequestOptions,
private _ToastStore: Store<ToastModel>,
private _LoaderStore: Store<boolean>) {
super(_XHRBackend, _RequestOptions);
}
public request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
return this.handleResponse(super.request(url, options));
}
public get(url: string, options?: RequestOptionsArgs): Observable<Response> {
this.beforeRequest(url);
return super.get(url, this.getRequestOptionArgs(options));
}
public post(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
this.beforeRequest(url, body);
return super.post(url, body, this.getRequestOptionArgs(options));
}
public put(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
this.beforeRequest(url, body);
return super.put(url, body, this.getRequestOptionArgs(options));
}
public delete(url: string, options?: RequestOptionsArgs): Observable<Response> {
this.beforeRequest(url);
return super.delete(url, this.getRequestOptionArgs(options));
}
private getRequestOptionArgs(options?: RequestOptionsArgs): RequestOptionsArgs {
if (options == null) {
options = new RequestOptions();
}
if (options.headers == null) {
options.headers = new Headers();
}
options.headers.append('Content-Type', 'application/json');
return options;
}
private handleResponse(response: Observable<Response>): Observable<Response> {
return response
.catch(this.onCatch)
.do(this.onSuccess.bind(this), this.onError.bind(this))
.finally(this.afterResponse.bind(this));
}
private beforeRequest(url: string, body?: string): void {
this._LoaderStore.dispatch({ type: ReducerActions.Loader.Set, payload: true });
}
private afterResponse(): void {
this._LoaderStore.dispatch({ type: ReducerActions.Loader.Set, payload: false });
}
private onCatch(error: any, caught: Observable<Response>): Observable<Response> {
console.log("interceptor catch called");
return Observable.throw(error);
}
private onSuccess(res: Response): void {
let response: ApiResponse<any> = res.json();
if (!response.message) {
return;
}
let toast: ToastModel = {
text: response.message,
duration: 5000,
type: "success"
};
this._ToastStore.dispatch({ type: ReducerActions.Toast.Update, payload: toast });
}
private onError(error: any): void {
let toast: ToastModel = {
text: "Error occurred!",
duration: 5000,
type: "failure"
};
this._ToastStore.dispatch({ type: ReducerActions.Toast.Update, payload: toast });
}
}
I hope this helps :) 我希望这有帮助 :)
As mentioned in comments, this is asynchronous, so while the request takes some time to execute, 正如评论中所提到的,这是异步的,所以虽然请求需要一些时间来执行,
this.showLoader = false;
// takes some time to execute
var k = this.myhttpService.authenticationt2c(...);
// executed while waiting for above code to execute
this.showLoader = true;
Instead, from your service, return an Observable and in component subscribe. 相反,从您的服务返回一个Observable并在组件订阅中。 Then inside the callback (subscribe) switch the boolean flag. 然后在回调(subscribe)内部切换布尔标志。 I'd guess that you would want to actually switch the boolean flag showLoader
to false
after the request have been completed, so I switched them around below: 我想你会想要在请求完成后将boolean标志showLoader
切换为false
,所以我在下面切换它们:
this.showLoader = true;
this.myhttpService.authenticationt2c(...)
.subscribe(() => this.showLoader = false)
and from the service, as said, return an Observable, so use map
instead of subscribe
: 从服务中,如上所述,返回一个Observable,所以使用map
而不是subscribe
:
this.http.request(req).map(event => { ... })
Check these links for reading up on asynchronicity: How do I return the response from an Observable/http/async call in angular2? 查看这些链接以了解异步性: 如何从angular2中的Observable / http / async调用返回响应? and How do I return the response from an asynchronous call? 以及如何从异步调用返回响应?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.