schema: {
data:
"permissions.resources.resource"
,
model: {
id:
"client_Permission_Id"
,
fields: {
"resourceno"
: { editable:
true
, nullable:
true
},
"uri"
: { editable:
true
},
"verb"
: { editable:
true
}
}
}
}
The service this datasource is connected to returns json like this:
{
"permissions"
: {
"resources"
: {
"resource"
: [
{
"client_permission_id"
:
"1"
,
"resourceno"
:
"6"
,
"uri"
:
"system/api/resources?verbs={verbs}&pathsearch={pathsearch}"
,
"verb"
:
"get"
},
{
"client_permission_id"
:
"2"
,
"resourceno"
:
"7"
,
"uri"
:
"system/api/resources/{resourceno}"
,
"verb"
:
"get"
}
]
}
}
}
It works fine, but the result from the service can be empty, and the json result will then look like this:
{
"permissions"
: {
"resources"
:
null
}
}
In this case the datasource will fail.It gives the following errormsg:
Uncaught TypeError: Cannot read property
'resource'
of
null
(anonymous
function
)
Class.extend.init.that.datakendo.web.js:5225
Observable.extend.successkendo.web.js:5630
e.extend.proxy.gjquery.min.js:2
Class.extend.read.options.successkendo.web.js:5118
f.Callbacks.njquery.min.js:2
f.Callbacks.o.fireWithjquery.min.js:2
wjquery.min.js:4
f.support.ajax.f.ajaxTransport.send.d
I understand that it fails because permissions.resources is null, but when this happens the datasource seems to enter a state it cannot recover from. If I now call the read() method on the datasource it will not result in a network call. Nothing happens at all.
How can I solve this?
7 Answers, 1 is accepted
that.data =
function
(data) {
var
record,
getter,
idx,
length,
modelInstance =
new
that.model();
try
{
data = dataFunction(data);
}
catch
(ex) {
return
{};
}
if
(data && !isEmptyObject(getters)) {
if
(toString.call(data) !==
"[object Array]"
) {
data = [data];
}
for
(idx = 0, length = data.length; idx < length; idx++) {
record = data[idx];
for
(getter
in
getters) {
record[getter] = modelInstance._parse(getter, getters[getter](record));
}
}
}
return
data;
};
I have just added the try/catch on the data = dataFunction(data) line. I guess there is a better way to solve this, but it solves my problem. Please fix this Kendo.
A custom schema data function should be used, when data is nested several levels within the response and you would expect some of those nested objects to be missing in some cases. For example:
dataSource: {
schema: {
data:
function
(data) {
if
(data && data.foo) {
if
(data.bar) {
return
data.bar;
}
}
return
[];
}
}
}
All the best,
Rosen
the Telerik team
I have created several generic widgets that all get given a DataSource, so I can't change the schema to ensure that this bug doesn't occur and granted, I could put the schema in the code that sets up the DataSource, but at the moment, the website is still in development and the schema's keeps changing so I'm not willing hard-code schema's in just yet (and, really, I shouldn't have to) and it really doesn't help that the only way I know something is wrong with the URL providing the data is a "Cannot read property 'slice' of null" (or similar) error in the browser, which is not very helpful.
As mentioned in the documentation, the error event is raised when there is a error during the AJAX request. Thus, it is not appropriate to raise it when there is an error with the actual data or its processing. Also the DataSource cannot recover from an error caused by incorrect structure of the provided data, therefore raising the error event will not help. The developer should ensure that the format of the provided data always match the description set via the schema.
All the best,Rosen
the Telerik team
That does make a lot of sense, however, that is rather an idealistic view. Sometimes schema changes can and do happen and without any notification or documentation changes (or knowledge of such changes); especially when using third party services.
Would it be extraordinarily difficult to wrap the parsing code in the DataSource in a Try...Catch and then raise an error and just keep the data array at whatever it was before parsing if an error does occur? At least that way the developer could handle it better and then display a useful user message (or perform a different action or retrieve data from an alternative source or etc, etc) and that way the failure is graceful and well handled. At the moment, if a schema change happens that we are not currently aware of, the error can only be handled by trapping the error at a very high level and we have absolutely no way of knowing which DataSource on a page has the issue.
The DataSource component provides the functionality of "data gathering and providing" (correct me if I'm wrong here), so shouldn't it be able to handle errors on both the gathering side (which it does) and the providing (which it does not)?
As I have stated this will not be appropriate. Swallowing the JavaScript error caused by malformed server response does not seems reasonable. However, if you find this appropriate for your scenario you are free to declare a custom schema data function and handle the changed response format there.
Regards,Rosen
the Telerik team