gpt4 book ai didi

Angular 6 : Observable async binding not working as expected after HttpErrorResponse

转载 作者:行者123 更新时间:2023-12-03 08:04:02 28 4
gpt4 key购买 nike

我正在尝试使用此处列出的 ErrorHandler 全局处理 Angular 错误:https://medium.com/@aleixsuau/error-handling-angular-859d529fa53a

我将错误消息转发到通知服务。应用程序组件模板使用异步管道绑定(bind)到服务提供的可观察对象。

当抛出客户端错误时,一切都按预期工作:错误被捕获,通知被发送并且 UI 正在显示错误消息。 3 秒后消息消失,因为 observable 变为空值。

在 HttpErrorResponses 上的行为很奇怪:错误被捕获,通知被发送,但 UI 没有更新。除非在 3 秒内抛出另一个 HttpErrorResponse!

我是否遗漏了什么或者这是 Angular 6 或 RxJs 中的错误?

我创建了一个 最小、完整和可验证的示例 在 stackblitz 上:
https://stackblitz.com/edit/angular-e9keuw

错误处理程序:

@Injectable()
export class ErrorSink implements ErrorHandler {

// ErrorHandler is created before the providers
// we have to use the Injector to get them
constructor(private injector: Injector) {}

handleError(error: Error | HttpErrorResponse) {
console.error('Caught error: ', error);

const notificationService = this.injector.get(NotificationService);

// client error
if (!(error instanceof HttpErrorResponse)) {
console.log('client error!');
return notificationService.notify(error.message);
}

// offline error
if (!navigator.onLine) {
console.log('No Internet Connection');
return notificationService.notify('No Internet Connection');
}

// http error
console.log(error.status, error.message);
return notificationService.notify(`${error.status} - ${error.message}`);
}
}

通知服务:
@Injectable()
export class NotificationService {

private subject: BehaviorSubject<string> = new BehaviorSubject(null);
readonly notification$: Observable<string> = this.subject.asObservable();

constructor() {}

notify(message) {
console.log('notification', message)

this.subject.next(message);
setTimeout(() => this.subject.next(null), 3000);
}
}

组件:
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {

constructor(
private notificationService: NotificationService,
private http: HttpClient
) {}

throwError(): void {
throw new Error('an error was thrown!');
}

loadUrl() {
this.http.get('https://www.google.com/').subscribe(
data => console.log(data)
);
}
}

和绑定(bind)模板:
<div *ngIf="notificationService.notification$ | async as notification">
{{ notification }}
</div>

最佳答案

原因是错误是在区域外触发的。我不知道发生这种情况的确切原因,因为我没有看到您的所有代码,但它是:)。更新 NotificationService 以在区域内运行通知:

@Injectable()
export class NotificationService {

private subject: BehaviorSubject<string> = new BehaviorSubject(null);
readonly notification$: Observable<string> = this.subject.asObservable();

private timeout: number = 0;

constructor(readonly zone: NgZone) {}

notify(message) {
console.log('notification', message)

clearTimeout(this.timeout);

this.zone.run(() => {
this.subject.next(message);
this.timeout = setTimeout(() => this.subject.next(null), 3000);
});
}
}

不过,有一个提示,将您的 setTimeout 引用保存在类成员中。这样,如果您在 3 秒内有两个错误,您可以取消 setTimeout。可能会发生第二个错误无法读取,因为它已设置为 null

关于 Angular 6 : Observable async binding not working as expected after HttpErrorResponse,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52856685/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com