Catchops Catchops - 1 month ago 37
Javascript Question

TypeError when using aurelia-fetch-client

I am using the aurelia-fetch-client version 1.0.1.

I execute the fetch within a service class that I have created, and I get an error stating:


TypeError: Cannot read property 'isProtoTypeOf' of undefined at eval
[filepath]aurelia-fetch-client.


The actual error is being thrown in the file aurelia-fetch-client on line 134. the code there is:

This code is from aurelia-fetch-client:

var promise = processRequest(request, this.interceptors).then(function (result) {
var response = null;

if (Response.prototype.isPrototypeOf(result)) { <<--PROBLEM IS HERE!!!! LINE 134
response = result;
} else if (Request.prototype.isPrototypeOf(result)) {
request = Promise.resolve(result);
response = fetch(result);
} else {
throw new Error('An invalid result was returned by the interceptor chain. Expected a Request or Response instance, but got [' + result + ']');
}

return request.then(function (_request) {
return processResponse(response, _this.interceptors, _request);
});
});


See above. I've annotated the line of code throwing the error. The "prototype" is null, so it is returning the given error message.

I had all of this working in a previous project, but using the beta version of the aurelia-fetch-client. The code below is very similar to the code calling the beta version of the aurelia-fetch-client.

The documentation states that I need to load a polyfill for this, so I load the "fetch" polyfill as specified (I'm doing this in main.js), but still keep getting this error. The same thing happens if I load it here in the service.

Has anyone every experienced this, and how have you solved it?

Here is some code of the service call and the base service:

import {inject} from 'aurelia-framework';
import {Configure} from 'aurelia-configuration';
import {HttpClient} from 'aurelia-fetch-client';

export class ServiceBase {

// *************************************************************
// Services Constructor
// Sets up the base http Client configuration
// *************************************************************
constructor(configure, httpClient) {

// Set up configuration and initial user token
this.userToken = 'tokenvalue'; //TODO: put real one in later, not used on this call
this.configure = configure;
this.httpClient = httpClient;

this.httpClient.configure(config => {
config
.withBaseUrl(this.configure.get('servicesBaseUrl'))
.withDefaults({
headers: {
'content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/x-www-form-urlencoded',
'X-Requested-With': 'Fetch'
},
mode: 'cors'
})
.withInterceptor({
request(request) {
console.log('KCU Class Requesting: ' + request.method + '; ' + request.url);
return request;
},
response(response) {
console.log('KCU Class Received: ' + response.status + '; ' + response.url);

if (response.status !== 200) {
throw response;
} else {
return response;
}

},
requestError(err) {
console.log('Request Error Receieved: ' + err.toString());
}
});
});

}

}


and the service that extends this base class:

import {inject} from 'aurelia-framework';
import {HttpClient, json} from 'aurelia-fetch-client';
import {Configure} from 'aurelia-configuration';
import {ServiceBase} from './serviceBase'

@inject(Configure, HttpClient)

export class HospitalService extends ServiceBase {

constructor(configure, httpClient) {
super(configure, httpClient);

this.configure = configure;

}

// ****************************************
// Extracts the list of hospitals for the initial search grid
// ****************************************
getHospitalListSearchGridData() {

let urlCompletion = '';

return this.httpClient.fetch(
this.configure.get('HospitalSearch') + urlCompletion, // This is the method name on the service to call
{
method: 'get',
headers: {
'Authorization': 'Bearer ' + this.userToken.toString()
}
}
)
.then(response => response.json())
.then(responseInfo => {
return responseInfo;
})
.catch(error => {
return false;
});

}

}


A little bit more information regarding the overall project is that this is being built inside of an existing ASP.NET MVC project. A new area is being created where the new set of screens will live which can also allow nice encapsulation of the files and dependencies, but utilize the existing service layer that provides the data interfaces.

Answer

For those of you who may come across this (or something similar), I've found the source of the issue.

This did not have anything to do with the polyfill. The JS code worked in the latest version of Chrome (v 54.xxx). And because it was not an older browser, the polyfill was not at fault. What WAS the problem was a javascript file clash.

The "Response" object was being overriddenn somehow and I had to determine where. Since this is living inside of a larger ASP.NET MVC application I looked up application tree to the main application's script files and found that there was, indeed, a response.js file being used. It was implemented long ago to help in accessing the service layer of our application suite.

When this was removed, the aurelia-fetch-client worked as advertised. The problem now is that some of the existing code accessing the services does not work properly. The solution for that is beyond the scope of this write up. Bottom line, it was JS clashing causing the problems.

Comments