You found a bug! We've classified it as EXTJS-9529 . We encourage you to continue the discussion and to find an acceptable workaround while we work on a permanent fix.
  1. #1
    Ext JS Premium Member
    Join Date
    Apr 2011
    Posts
    4
    Vote Rating
    1
    orbiz3 is on a distinguished road

      0  

    Default [4.2.0 / 4.2.1.-beta1] model load width emtpy result array brings an error

    [4.2.0 / 4.2.1.-beta1] model load width emtpy result array brings an error


    REQUIRED INFORMATION

    Ext version tested:
    • Ext 4.2.0 GA / 4.2.1.744-beta
    Browser versions tested against:
    • FF 20.0.1 (firebug 1.11.2 installed)
    Description:
    • If you try to load a model with a proxy ([your-model].load(...), and the resultset is empty, I get an error in firebug:
      TypeError: record is undefined
      if (!record.hasId()) {
    • In ExtJS 4.1.0 GA it's not a problem, if the resultset is empty
      When it's empty, the model is undefined
    Steps to reproduce the problem:
    • define a model with a ajax proxy and a json-reader
    • create an simple json-file (look at test-case) with an empty result array
    • get your model
    • load your model via: [your-model].load(id, {})
    • an error comes up -> "record is undefined" line: 69683 (ext-all-debug.js)
    • -> width ExtJS 4.1.0 GA you get on your success-methode at first arguments a model that was undefined
    The result that was expected:
    • on ExtJS 4.1.0 GA the result of an empty resultset of a ajax-reqest was a model that was undefined
    The result that occurs instead:
    • an error occurs
    Test Case:

    a user.json-File with a resultset:
    Code:
         
    {
        success: true,
        total: 1,
        users: [
            { id: 1, name: 'Test-User' , email: 'TEST-Email'}
        ]
    }
    the user.json-File to reproduce the error:
    Code:
         
    {
        success: true,
        total: 0,
        users: []
    }
    The test.html page:
    Code:
         
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html>
        <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="stylesheet" type="text/css" href="extjs/4.2.0/resources/css/ext-all.css"/>
        <script type="text/javascript" src="extjs/4.2.0/ext-all-debug.js" charset="UTF-8"></script>
        <script language="javascript"  type="text/javascript" charset="UTF-8">
        Ext.application({
            name: 'Test',
            launch: function() {
                Ext.define('User', {
                    extend: 'Ext.data.Model',
                    fields: ['id', 'name', 'email'],
                    proxy: {
                        type: 'ajax',
                        url : 'users.json',
                        reader: {
                            type: 'json',
                            root: 'users'
                        }
                    }
                });
            
                var user = Ext.ModelManager.getModel('User');
                var userID = 1;
                user.load(userID, {
                    success: function(user) {
                        console.log("argum", arguments)
                        if(user){
                            console.log("User found: " + user.getId() + ' - ' + user.get('name') + ' - ' + user.get('email'));
                        }else{
                            console.log("No User width ID: " + userID);
                        }
                    }
                });
            
            
                
            }
        });
        </script>
        </head>
        <body></body>
    </html>
    Possible fix:

    line: 69683 - ext-all-debug.js
    Code:
    load: function(id, config) {
      config = Ext.apply({}, config);
      config = Ext.applyIf(config, {
        action : 'read',
        id     : id
      });
      var operation = new Ext.data.Operation(config),
        scope = config.scope || this,
        record = null, callback;
      callback = function(operation) {
        if (operation.wasSuccessful()) {
    
         // Why you don't check, if the the result record exists?
         // In my test-case the record is undefined
          record = operation.getRecords()[0];
          if (!record.hasId()) {
            record.setId(id);
          }
          Ext.callback(config.success, scope, [record, operation]);
        } else {
          Ext.callback(config.failure, scope, [record, operation]);
        }
        Ext.callback(config.callback, scope, [record, operation]);
      };
      this.getProxy().read(operation, callback, this);
    }
    Operating System:
    • Win7

    Comment

    I don't know if this is a bug, but in ExtJS 4.1.0 it works (empty result brings an empty model)

    Did I miss something on upgrade from ExtJS 4.1.0 to ExtJS 4.2.0 ?
    Last edited by orbiz3; 18 Apr 2013 at 2:48 AM. Reason: wrong test case ( json: "total" attribute should be "0")

  2. #2
    Sencha - Support Team slemmon's Avatar
    Join Date
    Mar 2009
    Location
    Boise, ID
    Posts
    4,800
    Vote Rating
    167
    slemmon is a splendid one to behold slemmon is a splendid one to behold slemmon is a splendid one to behold slemmon is a splendid one to behold slemmon is a splendid one to behold slemmon is a splendid one to behold slemmon is a splendid one to behold

      0  

    Default


    Thanks for the report! I have opened a bug in our bug tracker.

  3. #3
    Sencha - Ext JS Dev Team evant's Avatar
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    16,648
    Vote Rating
    583
    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


    The response returned by the server is a bit questionable. We're asking it to load a single model and it means it doesn't exist or couldn't load it. Is that a success? I'd say it's not, because we don't end up with what we wanted from the server.

    Even if we do return success, it's still a failure because there's no data. As such, the code will change so that it will be able to handle a combination of

    Code:
    success: true,
    items: []
    However, it will fire the failure callback.
    Evan Trimboli
    Sencha Developer
    Twitter - @evantrimboli
    Don't be afraid of the source code!

  4. #4
    Ext JS Premium Member
    Join Date
    Apr 2011
    Posts
    2
    Vote Rating
    0
    orbiz2 is on a distinguished road

      0  

    Default


    Quote Originally Posted by evant View Post
    The response returned by the server is a bit questionable. We're asking it to load a single model and it means it doesn't exist or couldn't load it. Is that a success? I'd say it's not, because we don't end up with what we wanted from the server.

    Even if we do return success, it's still a failure because there's no data. As such, the code will change so that it will be able to handle a combination of

    Code:
    success: true,
    items: []
    However, it will fire the failure callback.

    I don't really get why you consider an empty result set a failure state.

    I understand success:false to indicate an actual error state, i.e. there was an exception thrown server side or similar, and could be used to indicate that a record couldn't be loaded. But a result set being empty does not simply imply a failure occurred. Do you know of a single DB driver that indicates an error state when a query returns an empty result set?

    When loading a model using a surrogate key, one could perhaps considered an empty result a failure state. But some shops have legacy schemas and use natural keys too. Imagine a scenario where a client needs to check the uniqueness of an email address, which is the natural primary key in a table, and has only a CRUD interface to do so. How do you check for uniqueness? Until this bug, you could send a read operation to the server, and check for an empty result set. success:true, count:0...no exception has been thrown, no kittens were harmed, just an empty result set.

    Now imagine your shop has many such scenarios and a code base which depends on such requests NOT being considered failures? Time to refactor? I ask why.

    Sam

  5. #5
    Sencha - Ext JS Dev Team evant's Avatar
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    16,648
    Vote Rating
    583
    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


    But we're explicitly asking to load a single model. If, at all the end of it, you don't get a model back, surely that's a "failure", because it was unable to achieve the result.

    Though it may not make sense for your use case, I think it would be an expected behaviour to fail if there are no records returned.
    Evan Trimboli
    Sencha Developer
    Twitter - @evantrimboli
    Don't be afraid of the source code!

  6. #6
    Ext JS Premium Member
    Join Date
    Apr 2011
    Posts
    2
    Vote Rating
    0
    orbiz2 is on a distinguished road

      0  

    Default


    Expected behavior for me would be to have my failure callback called if the server returned success:false.

    What exactly is the purpose of the condition:
    Code:
    if (operation.wasSuccessful()) {
    ...if not to determine if the operation was a success or not?

    So ExtJS will now ignore the (authoritative) response from the server indicating that the operation was successful, only to make a decision about its validity for me?

    Can you provide me any other reason why this behavior should be changed other than your personal interpretation of well-formedness?

  7. #7
    Sencha Premium Member
    Join Date
    Nov 2012
    Posts
    2
    Vote Rating
    0
    C.Parcell is on a distinguished road

      0  

    Default


    What is the status of this? I am having this same issue.

    ExtJS 4.2.1.883

    record is undefined

    operation.wasSuccessful() is returning true when no records are returned.

    If you have done something wacky with what or how you define success, then you may want to also check if record == undefined.

    Or is there some other process to check for records prior than requesting them?

  8. #8
    Sencha User
    Join Date
    Mar 2011
    Posts
    146
    Vote Rating
    4
    incutonez is on a distinguished road

      0  

    Default


    I'm having this issue with the latest build of 4.2.1 as well. My issue is that some models do not contain data for a certain hasOne relationship, so if I try to use the getter on these models (with no data for the relationship), I get the error:

    TypeError: record is undefined (ext-all-dev.js: 100283)
    if (!record.hasId()) {

    I can't even call the getter and then check to see if I got something returned... it just stops the show completely, but that's because record is undefined, and it's not being checked for in that if statement on line 100283.

    Anyway, my current work-around will be using the model's getAssociatedData function, and checking to see if my getter exists in there... if it does, proceed to use it, otherwise, never call it.