Thank you for reporting this bug. We will make it our priority to review this report.
  1. #1
    Ext JS Premium Member
    Join Date
    Mar 2009
    Posts
    20
    Vote Rating
    1
    chrisbrianolsen is on a distinguished road

      1  

    Default [FIXED-EXTJSIV-224] http 204 (No Content) return error

    [FIXED-EXTJSIV-224] http 204 (No Content) return error


    Guys,
    I have a REST Resource that returns a 204 (No Content) when there is no data.
    ExtJS blows up trying to read the root element from the data.
    Shouldn't it either throw an exception or skip trying to read data when a 204 is returned ?

    Thanks
    Chris Olsen

  2. #2
    Sencha - Ext JS Dev Team evant's Avatar
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    16,915
    Vote Rating
    630
    evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute

      0  

    Default


    This should be fixed as of B1. Now if you return a 204 the store will fire a load event with no records.
    Evan Trimboli
    Sencha Developer
    Twitter - @evantrimboli
    Don't be afraid of the source code!

  3. #3
    Sencha Premium Member
    Join Date
    Jan 2008
    Location
    San Francisco Bay, CA
    Posts
    41
    Vote Rating
    1
    rgralhoz is on a distinguished road

      0  

    Question Which version has this fix?

    Which version has this fix?


    @evant, I see the same problem in 4.1.3. Which version has the mentioned fix for this bug?

  4. #4
    Sencha - Ext JS Dev Team evant's Avatar
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    16,915
    Vote Rating
    630
    evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute

      0  

    Default


    Can you elaborate? Perhaps if you could post a fiddle: https://fiddle.sencha.com/
    Evan Trimboli
    Sencha Developer
    Twitter - @evantrimboli
    Don't be afraid of the source code!

  5. #5
    Sencha Premium Member
    Join Date
    Jan 2008
    Location
    San Francisco Bay, CA
    Posts
    41
    Vote Rating
    1
    rgralhoz is on a distinguished road

      0  

    Default Sample

    Sample


    @evant , the link doesn't include ExtJs 4.1.3.

    Please check a simplified version of my code bellow.

    My store:

    PHP Code:
    Ext.define('My.store.Devices', {

     
    extend'Ext.data.Store',

        
    requires: [        'My.model.Device'    ],

        
    autoLoadtrue,

        
    storeId'Devices',

        
    model'My.model.Device'

    }); 
    Here is my model, its proxy and its reader:

    PHP Code:

    Ext
    .define('My.model.Device', { 

        
    extend'Ext.data.Model',

        
    fields: [        {            

             
    name'id'

            
    mapping'@key'

            
    type'int',

            
    sortablefalse      

           
    },       {

                
    name'name',

                
    sortabletrue

            
    }
        ],

        
    proxy: {       

            
    type'rest',

            
    url'/api/myrest/devices',

            
    headers: {

                
    Accept'application/devices+json;version=1'

            
    },

            
    enablePagingtrue,

            
    simpleSortModetrue

            
    reader: {

                
    type'json',

                
    root'devices.device',

                
    idProperty'id',  

                
    totalProperty'devices["@size"]'    

            
    }//reader

        
    //proxy

    }); 
    To define a filter I use the extraParams proxy property:

    PHP Code:
    store.proxy.extraParams= {      filter"(id eq 7)"     }; 
    Here is a HTTP response from the REST API when there is data:

    PHP Code:
    RESPONSE HEADERS
    Status Code
    200 OK
    Content
    -Typeapplication/devices+json;version="1"

    RESPONSE BODY
    {  "devices": {

            
    "@uri""api/myrest/devices",

            
    "@size""1",

            
    "device": [{   "@key""7",     "name""foo"    }]

        }



    Finally. here is the HTTP response from the REST API when there is NO data. Please note that there is no content on the response body:

    PHP Code:

    RESPONSE HEADERS
    Status Code
    204 No Content

    RESPONSE BODY 

    Now if I try to load my store with a filter that returns no results (say id =1)...

    PHP Code:
    store.proxy.extraParams= {      filter"(id eq 1)"     };
    store.loadPage(1); 
    ... then I get the following error, and my grid loading mask stays on and on...
    • Uncaught TypeError: Cannot read property 'device' of undefined
      (anonymous function)
      Ext.define.readRecords ext-all-dev.js:86683
      Base.implement.callParent ext-all-dev.js:6431
      Ext.define.readRecords ext-all-dev.js:87313
      Ext.define.read ext-all-dev.js:86622
      Ext.define.processResponse ext-all-dev.js:87959
      (anonymous function) ext-all-dev.js:88471
      Ext.apply.callback ext-all-dev.js:11434
      Ext.define.onComplete ext-all-dev.js:37132
      Ext.define.onStateChange ext-all-dev.js:37069
      (anonymous function) ext-all-dev.js:3000

    Last edited by rgralhoz; 21 Oct 2013 at 11:25 AM. Reason: format

  6. #6
    Sencha - Ext JS Dev Team evant's Avatar
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    16,915
    Vote Rating
    630
    evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute

      0  

    Default


    In this case, the original issue is still fixed. You're asking for a custom root/totalProperty when they may not exist. In the case of an empty response (no responseText), it will pass the response object to the root/total:

    Code:
    Ext.define('My.model.Device', {
        extend: 'Ext.data.Model',
        fields: [{
            name: 'id',
            mapping: '@key',
            type: 'int',
            sortable: false
        }, {
            name: 'name',
            sortable: true
        }],
        proxy: {
            type: 'rest',
            url: 'data.json',
            headers: {
                Accept: 'application/devices+json;version=1'
            },
            enablePaging: true,
            simpleSortMode: true,
            reader: {
                type: 'json',
                root: function(data) {
                    if (data.hasOwnProperty('responseText')) {
                        return null;
                    }
                    return data.devices.device;
                },
                idProperty: 'id',
                totalProperty: function(data) {
                    if (data.hasOwnProperty('responseText')) {
                        return null;
                    }
                    return data.devices['@size'];
                }
            }
        }
    });
    Evan Trimboli
    Sencha Developer
    Twitter - @evantrimboli
    Don't be afraid of the source code!

  7. #7
    Sencha Premium Member
    Join Date
    Jan 2008
    Location
    San Francisco Bay, CA
    Posts
    41
    Vote Rating
    1
    rgralhoz is on a distinguished road

      0  

    Default


    Thanks for the answer, @evant. Your suggestion works my given example.

    In this case, the original issue is still fixed.
    Right, but there is still an issue with Json reader when the HTTP response is Status Code: 204 No Content and at least one of the pair root/totalProperty is not a direct property of the returned json.


  8. #8
    Sencha Premium Member
    Join Date
    Jan 2008
    Location
    San Francisco Bay, CA
    Posts
    41
    Vote Rating
    1
    rgralhoz is on a distinguished road

      0  

    Default


    I believe this should fix the issue in the root cause, on the Ext.data.reader.Json:createAccessor() method. We should check for the "parent" property before calling the "child" one. The difference is marked bellow.

    Code:
    createAccessor: (function() {
            var re = /[\[\.]/;
    
            return function(expr) {
                if (Ext.isEmpty(expr)) {
                    return Ext.emptyFn;
                }
                if (Ext.isFunction(expr)) {
                    return expr;
                }
                if (this.useSimpleAccessors !== true) {
                    var i = String(expr).search(re);
                    if (i >= 0) {
                        return Ext.functionFactory('obj', 
    
                            'return obj' + (i > 0 ? 
    
                            '.hasOwnProperty("' + 
                                         expr.substring(0,i)  +
                                         '")? obj.' + expr + ' : null' : 
    
                            expr));
                    }
                }
                return function(obj) {
                    return obj[expr];
                };
            };
        }()),
    I'm not sure this fix would cause regression, but it worked for my cases.
    Last edited by rgralhoz; 22 Oct 2013 at 4:52 PM. Reason: format and details about solution

  9. #9
    Sencha Premium Member
    Join Date
    May 2011
    Posts
    27
    Vote Rating
    5
    kpiland is on a distinguished road

      0  

    Default


    So I just ran into this issue too in Ext JS 4.2.2.1144.

    I think my case is slightly different from the above, though, because I was not specifying a value for 'root'. I don't need to do that because the response is the array of data that I need. Works fine when there is data.

    If the service returns a 204 when there is no data, then by definition there is no response body and there is no responseText on the response object.

    So in Reader.read, no responseText makes it call the readRecords method, giving it the response object as the 'data' argument. Eventually, that works its way down to this block in Reader's readRecords method:

    Code:
    // Only try and extract other data if call was successful
    if (me.readRecordsOnFailure || success) {
        // If we pass an array as the data, we dont use getRoot on the data.
        // Instead the root equals to the data.
        root = Ext.isArray(data) ? data : me.getRoot(data);
        ...
    Because I have not specified anything for the root, the getRoot method is the identity function and simply returns the response object. So the subsequent code motors along thinking that the response object is a data record, which of course it is not. In the end, the Json reader thinks it has read 1 record with no data fields set on it. I suppose if any of your model fields happened to match up to fields on the response object, you might think you got something, but it could be really wacky.

    Following evant's suggestion, I could put this in the reader definition for my store's proxy:

    Code:
    ...
        reader: {
            type: 'json',
            root: function(data){
                if (data.hasOwnProperty('responseText')){
                    return null;
                }
                return data;
            }
        }
    ...

    I attempted the fix suggested by rgalhoz, but either I did it wrong or it had no effect for this case.

    Seems like this is still a bug to me. I'd expect Ext to acknowledge the 204 and return an empty data set without needing to jump through hoops. While the one suggestion works, it could be a pain to have to do that in a larger system wherever we might get such a response.

  10. #10
    Sencha Premium Member
    Join Date
    Jan 2008
    Location
    San Francisco Bay, CA
    Posts
    41
    Vote Rating
    1
    rgralhoz is on a distinguished road

      0  

    Default


    Hi, @kpilandMy fix was for ext.js 4.1.3 and so far I didn't get any regression. Best,

Similar Threads

  1. Replies: 11
    Last Post: 5 Mar 2014, 6:41 PM
  2. Replies: 0
    Last Post: 30 Mar 2011, 1:35 PM
  3. Replies: 0
    Last Post: 21 Mar 2011, 1:00 PM
  4. [FIXED] http://extjs.com/explorer page error
    By kdragon in forum Ext GWT: Bugs (1.x)
    Replies: 1
    Last Post: 20 Sep 2008, 8:21 PM
  5. Replies: 5
    Last Post: 29 Aug 2008, 11:38 AM

Thread Participants: 3