DataSource bug - if read fails it is not possible to call read again

8 posts, 1 answers
  1. Roger
    Roger avatar
    6 posts
    Member since:
    Oct 2011

    Posted 03 May 2012 Link to this post

    I have a datasource schema like this:

    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?
  2. Roger
    Roger avatar
    6 posts
    Member since:
    Oct 2011

    Posted 03 May 2012 Link to this post

    After posting this I found this forum post: http://www.kendoui.com/forums/ui/grid/xml-binded-datasource-with-empty-data-doesn-t-work-in-grid.aspx It seems to be a similar problem which then was fixed in an internal build, but I'm using the latest build, but it does not work for me. Could it be that this fix didn't make it into the official release? I have not tried the build attached in that post because it is not an option because I use many of the new features from the latest release. I can not use a build from january.
  3. Roger
    Roger avatar
    6 posts
    Member since:
    Oct 2011

    Posted 07 May 2012 Link to this post

    I fixed the bug myself. I did the following change i kendo.web.js

    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.
  4. Answer
    Rosen
    Admin
    Rosen avatar
    3253 posts

    Posted 08 May 2012 Link to this post

    Hi Roger,

    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
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  5. Chris
    Chris avatar
    25 posts
    Member since:
    Apr 2011

    Posted 01 Mar 2013 Link to this post

    If there was an error reading or (in this case) parsing the data, shouldn't the DataSource object still catch the error and raise the Error event with the exception, rather than just allowing it to be uncaught and, more importantly un-catchable by the developer (it happens in a callback of the ajax call, so we can't wrap the Read method on the DataSource).

    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.
  6. Rosen
    Admin
    Rosen avatar
    3253 posts

    Posted 05 Mar 2013 Link to this post

    Hi Chris,

    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
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  7. Chris
    Chris avatar
    25 posts
    Member since:
    Apr 2011

    Posted 18 Mar 2013 Link to this post

    Hi Rosen,

    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)?
  8. Rosen
    Admin
    Rosen avatar
    3253 posts

    Posted 19 Mar 2013 Link to this post

    Hello Chris,

    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
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
Back to Top