Reputation: 379
Back-end code is C# in .NET targeting the 4.6.1 framework. Front-end was recently upgraded from Angular 4 to Angular 8. Along with that webpack went from version 2.3 to version 4.41 and typescript from 2.2 to 3.2.4.
The code itself hasn't changed.
C#:
public override Task OnAuthorizationAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
{
var reject = false;
var principal = actionContext.RequestContext.Principal as ClaimsPrincipal;
if (principal == null || !principal.Identity.IsAuthenticated || reject) {
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized,
new { error = "Unauthorized request for Impersonate Mode" },
actionContext.ControllerContext.Configuration.Formatters.JsonFormatter);
return Task.FromResult<object>(null);
}
return Task.FromResult<object>(null);
}
Typescript:
actionErrorResponseHandler(response: Response) {
if(response.status === 401){
if(response.text().includes("Impersonate")){
this.displayText = ImpersonateRejectText;
}
this.show();
}
}
(EDIT) Called like so:
setupPopUpModal(modalHeader: string, displayText: string){
this.accountService.accountShowPopUpModal()
.pipe(catchError((response: Response) => this.rejectModal.actionErrorResponseHandler(response)))
.subscribe((result: string) => {
if(result == "Done"){
this.modalHeader = modalHeader;
this.displayText = displayText;
this.messageBoxModal.show();
}
})
}
Previously this worked fine. Now it generates an error that says "e.text is not a function"
If I look in Chrome's dev tools I see this from before the upgrade:
And this afterwards:
The .text() function is trying to return the body as a string, but the body does not exist anymore. The message I'm trying to search is now in e.error, but in Angular/Typescript "response.error" is not valid code.
I'm assuming I need to build and/or parse the response differently but I've not been able to find any documentation on this. Any help would be much appreciated.
Upvotes: 0
Views: 117
Reputation: 1847
I would assume that the old Angular version was prior to 4.3 ?
With 4.3 the regular HTTP request changed from "Http" to "HttpClient". The main change is that you do not get the response as a result, but only the (json) response body. And if the request was not a success (and a 401 isn´t one :-) ), than it errors out.
Therefor you have to catch the error and handle it. This can be done multiple ways. I would assume that you use RxJs to handle the response. Then your code may look like that
let response: SomeTyp;
this.httpClient.get<SomeTyp>('myBackendUrl').subscribe( (result) => response = result);
As a result, if your backend call returns a 400, the "regular" subscription will not be executed. Therefor response
stays empty.
One solution could be to handle the error case in the subscribe
let response: SomeTyp;
this.httpClient.get<SomeTyp>('myBackendUrl').subscribe(
(result) => response = result,
(errorCase) => this.handleTheError(errorCase)
);
private handleTheError(errorCase:ttpErrorResponse):void {
if(response.status === 401){
if(response.text().includes("Impersonate")){
this.displayText = ImpersonateRejectText;
return
}
}
throw Error('Unexpected Backend Response');
}
A second solution would be to handle it in the stream
let response: SomeTyp;
this.httpClient.get<SomeTyp>('myBackendUrl').pipe(
catchError( (errorCase:ttpErrorResponse) => // Handle the error )
).subscribe(
(result) => response = result
);
The advantage of "catchError" is, that you can catch the error and if it is an "expected" error that you can handle gracefully, just return a valid value. Then this value will be handled by the subscribe exactly like when you would have get a valid backend response.
If the error is NOT possible to handle gracefully, you can still throw it again
return throwError(errorCase);
And then handle it in the subscribe.
Upvotes: 1