简体   繁体   English

我应该如何在Angular中等待http请求完成?

[英]How should I wait for http request to complete in Angular?

I've been trying to learn Angular (Typescript) + ASP Net Core and I dont understand how should I wait for an observable to complete. 我一直在努力学习Angular(Typescript)+ ASP Net Core,我不明白我应该如何等待observable完成。 Basically, i've created a login service on the backend, which works. 基本上,我在后端创建了一个登录服务,它可以工作。 However, i've tried to create a simple helper to handle http responses easier on the client side. 但是,我试图创建一个简单的帮助程序,以便在客户端更容易处理http响应。 The issue is that it runs two times: on the first one it thinks RequestResponse is undefined (because it skips the http request) while on the second the RequestResponse is populated and it works as expected. 问题是它运行了两次:在第一个上它认为RequestResponse是未定义的(因为它跳过了http请求),而在第二个时,RequestResponse被填充并且它按预期工作。

Here's the Http helper: 这是Http助手:

 get<T>(url: string): Observable<T> {
    let options = this.doHeaders();
    return this.doSub(this.http.get(this.doUrl(url), options));
}

private doSub<T>(obs: Observable<Response>) {
    var ob1: Observable<T> = obs.map(this.extractData)
        .catch(this.handleError);

    return ob1;
}

Here's the RequestResponse: 这是RequestResponse:

export class RequestResponse {
   public error: string;
   public isOk: boolean;
   public code : StatusCode; 
}

Here's the Service: 这是服务:

@(Injectable)
export class RequestService {

constructor(
    private net: NetworkService,
    private loaderService: LoaderService,
    private storage: StorageService,
) {
}

login(email: string, password: string, rememberMe: boolean = false): RequestResponse {
    var r = new RequestResponse();

     // I need to make this wait
     this.net.get<LoginModel>(`Authentication/Login/${email}/${password}`).subscribe(t => {
            this.storage.token = t.token;
            this.storage.email = rememberMe ? email : null;
            this.storage.password = rememberMe ? password : null;
            this.storage.user = t.user;
            r.isOk = true;
            r.code = StatusCode.OK;
        },
        error => {
            r.isOk = false;
            switch (error.message) {
            case '403':
                    r.code = StatusCode.Forbidden; r.error = 'You've been suspended'; return;
            case '404':
                    r.code = StatusCode.NotFound; r.error = 'User not found'; return;
            case '406':
                    r.code = StatusCode.NotAcceptable; r.error = 'Invalid Email/Password'; return;
            default:
                r.code = StatusCode.InternalServerError; r.error = 'Internal Error'; return;
            }
        });

    // First time it is skipping all the way down, returning null
    return r;
   }
}

Here's how i'm trying to use it: 这是我试图使用它的方式:

login() {

    this.loginResponse = this.requestService.login(this.email, this.password, this.rememberMe);
    console.log(this.loginResponse);
    if (!this.loginResponse.isOk) {
        this.toasterService.pop('error', 'Error', this.loginResponse.error);
        return;
    }
    this.router.navigateByUrl('/home');
}

I've read about Promises and Observables and I've tried many changes, but the first RequestResponse being null was still a problem. 我已经阅读了Promises和Observables,我尝试了很多更改,但第一个RequestResponse为null仍然是个问题。

How should I deal with this? 我应该怎么处理这个?

It is recommended that you use the subscribe in the component, not in the service. 建议您在组件中使用subscribe,而不是在服务中使用。 That way you will have a better mechanism to react when the subscription is complete, plus provide ways to cancel or unsubscribe. 这样,您将有更好的机制在订阅完成时作出反应,并提供取消或取消订阅的方法。

Code from my service 我的服务代码

getProducts(): Observable<IProduct[]> {
    return this.http.get<IProduct[]>(this.productsUrl)
                    .pipe(
                        tap(data => console.log(JSON.stringify(data))),
                        catchError(this.handleError)
                    );
}

Code from my component 我的组件代码

ngOnInit(): void {
    this.productService.getProducts().subscribe(
        (products: IProduct[]) => {
            this.products = products;
            // Any code to be run after the subscription is complete goes here
        },
        (error: any) => this.errorMessage = <any>error
    );
}

For a "complete" sample application, check out my github repo: https://github.com/DeborahK/Angular-GettingStarted 对于“完整”示例应用程序,请查看我的github存储库: https//github.com/DeborahK/Angular-GettingStarted

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM