I am using TypeScript and Rxjs. I am sending data to the server using Rxjs. I have also implemented a custom interceptor. The interceptor returns a type:0
event and also the response from the server as two separate events. I suppose type:0
means that the request has been sent.
I don't want to do anything when type:0
event is received so I have put checks in the code to ignore it but my code still executes a piece of logic even if the event is type:0
. Have I made a mistake?
The code where I send the request is
let response:ServerResponseAPI = this.dataManagementService.addData(this.newData);
console.log("add practice question - response is ",response); //I see this print
if (response != null) { //for type:0, this should be null but isn't
let isResponseStructureOK: boolean = this.helper.validateServerResponseStructure(response);
if (isResponseStructureOK) {
console.log("received response from server: " + response.result);
let dialogComponentRef: ComponentRef<DialogBoxComponent> = this.maxFilesDialogContainerRef.createComponent(this.dialogFactory);
dialogComponentRef.instance.dialogMessage = response.result + ": " + response['additional-info'];
dialogComponentRef.instance.dialogID = "maxFilesDialog";
dialogComponentRef.instance.dialogShow();
return;
} else { //response structure not ok
console.log("received incorrect response structure from server: ", response);
let dialogComponentRef: ComponentRef<DialogBoxComponent> = this.maxFilesDialogContainerRef.createComponent(this.dialogFactory);
dialogComponentRef.instance.dialogMessage = "Server error";
dialogComponentRef.instance.dialogID = "maxFilesDialog";
dialogComponentRef.instance.dialogShow();
return;
}
} //end of not null response
addData is
addData(data:Data):ServerResponseAPI{
console.log("In DataManagementService: addData: ",data);
return this.bs.createData(data).subscribe((resBody/*:any*/)=>{
if(resBody != null) { //null means that the response wasn't an HttpResponse but probably some internal Rxjs event (eg type 0)
console.log('response from server:', resBody);
<ServerResponseAPI>resBody; //returning response body which is of type ServerResponseAPI;
}
else null; //this means type0 event
});
}
and bs.createData is
public createData(data:Data):any{
console.log('contacting server at '+this.API_URL +this.NEW_DATA_URL +" with data "+data+ " with httpOptions "+httpOptions.withCredentials + ","+httpOptions.headers );
let newData = new DataAPI(data)
let body = JSON.stringify(newData);
return this.http.post(this.NEW_DATA_URL,body,httpOptions)
.map(response => { //I suppose this could be any event from custom interceptor
if(response instanceof HttpResponse)
{
console.log('response from backend service:', response);
let result = <HttpResponse<any>>response;
return result.body; //return body of response which ideally should be of type ServerResponseAPI
}
else {
console.log("not an http response")
return null; //returning null for non-HttpResponse type
}
})
.catch(this.handleError); //error handler if Observable fails
}
The interceptor is
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
console.log("outgoing request",request);
const idToken = localStorage.getItem("id_token"); //JWT authentication stuff
console.log("id token is "+idToken);
if (idToken) {
const cloned = request.clone({
headers: request.headers.set("X-Auth-Token",
idToken)
});
console.log("new outgoing request", request);
return next.handle(cloned)
.do((ev: any) => {
console.log("got an event",ev)
})
.catch(errorResponse => {
console.log("caught error from server",errorResponse)
return observableThrowError(errorResponse);
});
}
else {
return next
.handle(request)
.do((ev: any) => {
console.log("got an event",ev)
})
.catch(errorResponse => {
console.log("caught error from server",errorResponse)
return observableThrowError(errorResponse);
});
}
}
When I run the code, I see this message which I shouldn't
got an event {type: 0}
new-data.component.ts:255 add data- response is Subscriber {closed: false, _parent: null, _parents: null, _subscriptions: Array(1), syncErrorValue: null, …}
new-practice-question.component.ts:270 received incorrect response structure from server: Subscriber {closed: false, _parent: null, _parents: null, _subscriptions: Array(1), syncErrorValue: null, …}
I suppose I get HttpEvent
from Rxjs
which is a union of HttpResponse.
type HttpEvent<T> = HttpSentEvent | HttpHeaderResponse | HttpResponse<T> | HttpProgressEvent | HttpUserEvent<T>;
How could I check that HttpEvent
is of type HttpResponse
?
Take a look at this piece of code you have:
addData(data:Data):ServerResponseAPI{
console.log("In DataManagementService: addData: ",data);
return this.bs.createData(data).subscribe((resBody/*:any*/)=>{ (...)
Now look at this one a few lines before:
let response:ServerResponseAPI = this.dataManagementService.addData(this.newData);
There are few things not correct there:
1- addData does not return an object of type/interface ServerResponseAPI, it returns a subscription object from your subscription action, so that you can do subscription.unsubscribe() later on if needed.
2- What you have in your response variable is not a response, you are treating that piece of code as if it were synchronous, it is not.