1. #1
    Sencha User
    Join Date
    Feb 2012
    Posts
    2
    Vote Rating
    3
    Basta is on a distinguished road

      2  

    Default Unanswered: Issue when hasOne association is null

    Unanswered: Issue when hasOne association is null


    I have the following data models:
    Code:
    Ext.regModel('Result', {
        associations: [
            {
                type: 'hasOne',
                model: 'Score',
                associationKey: 'halfTime',
                getterName: 'getHalfTime'
            },
            {
                type: 'hasOne',
                model: 'Score',
                associationKey: 'fullTime',
                getterName: 'getFullTime'
            },
            {
                type: 'hasOne',
                model: 'Score',
                associationKey: 'overTime',
                getterName: 'getOverTime',
                autoLoad: false
            },
            {
                type: 'hasOne',
                model: 'Score',
                associationKey: 'afterPenalties',
                getterName: 'getAfterPenalties',
                autoLoad: false
            }    
        ]
    });
    
    Ext.regModel('Score', {
        fields: [
            {name : 'home', type : 'int', optional: true, defaultValue: null}, 
            {name : 'away', type : 'int', optional: true, defaultValue: null}
        ],
        belongsTo: 'Result'
    });
    Now the problem is that some of the associations can be NULL in the received JSON data. Example:

    Code:
    "result":{
       "halfTime":{
          "home":3,
          "away":0
       },
       "fullTime":{
          "home":4,
          "away":1
       },
       "overTime":null,
       "afterPenalties":null
    }
    In this case if I try to access the data like

    Code:
    var score = result.getFullTime();
    It results in the error:

    Code:
    Uncaught TypeError: Cannot call method 'indexOf' of undefined
    If I remove the 'overTime' and 'afterPenalties' association it all works fine with the above data. I don't understand how I should add 'optional' associations.

  2. #2
    Sencha - Senior Forum Manager mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    37,525
    Vote Rating
    871
    Answers
    3564
    mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute

      0  

    Default


    First suggestion is you shouldn't use Ext.regModel in ST2 anymore, instead you should use Ext.define:

    Code:
    Ext.define('Result', {
        extend : 'Ext.data.Model',
    
        config : {
            hasOne : [
                {
                    associatedModel : 'Score',
                    associationKey  : 'halfTime',
                    getterName      : 'getHalfTime',
                    associatedName  : 'halfTime'
                },
                {
                    associatedModel : 'Score',
                    associationKey  : 'fullTime',
                    getterName      : 'getFullTime',
                    associatedName  : 'fullTime' },
                {
                    associatedModel : 'Score',
                    associationKey  : 'overTime',
                    getterName      : 'getOverTime',
                    associatedName  : 'overTime'
                },
                {
                    associatedModel : 'Score',
                    associationKey  : 'afterPenalties',
                    getterName      : 'getAfterPenalties',
                    associatedName  : 'afterPenalties'
                }
            ]
        }
    });
    
    Ext.define('Score', {
        extend : 'Ext.data.Model',
    
        config : {
            fields: [
                {name : 'home', type : 'int', optional: true, defaultValue: null},
                {name : 'away', type : 'int', optional: true, defaultValue: null}
            ],
            belongsTo: 'Result'
        }
    });
    Running this against our latest code it only errors out when I execute getOverTime or getAfterPenalties because I don't have a url specified in a proxy on the Score model as it is trying to load the model because data isn't present.
    Mitchell Simoens @SenchaMitch
    Sencha Inc, Senior Forum Manager
    ________________
    Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
    https://github.com/mitchellsimoens

    Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/

    Need more help with your app? Hire Sencha Services services@sencha.com

    Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is in print!

    When posting code, please use BBCode's CODE tags.

  3. #3
    Sencha User
    Join Date
    Feb 2012
    Posts
    2
    Vote Rating
    3
    Basta is on a distinguished road

      1  

    Default


    Thank you for your response. It appears that if you use a hasOne association the data really has to have a related record and can't have null. I've ended up using a hasMany association, which can accept 0 or more related record. I can then look at result.overTime().count to see if it has a overTime result or not. I would expect that similar would be possible with a hasOne association but can't get that working. For now I can live with the above.

  4. #4
    Sencha Premium Member
    Join Date
    Mar 2012
    Location
    Westbrook, ME
    Posts
    117
    Vote Rating
    3
    sfpc2770 is on a distinguished road

      0  

    Default hasOne association is null

    hasOne association is null


    So is there a way to avoid this error when it is a valid scenario? Some way to not have the proxy attempt to load the data if the data truly isn't there?

  5. #5
    Sencha Premium Member
    Join Date
    May 2012
    Posts
    9
    Vote Rating
    0
    clarkstachio is on a distinguished road

      0  

    Default


    I too have the same issue. I'm using a rest proxy, and if my associated object is null, it will attempt to autoload the data via the proxy. This is an issue of course, because my business model allows in many places for null hasOne relationships, where the data doesn't exist.

    To work around this for now, I am returning an empty array in the json instead of null. The model then does not attempt to autoload because it has a dummy object already loaded for the association.

    Has anyone found a valid solutions to this?

  6. #6
    Sencha User
    Join Date
    Dec 2011
    Posts
    156
    Vote Rating
    3
    Answers
    8
    coolfish is on a distinguished road

      0  

    Default


    I haven't yet. I am encountering a similar problem now, except the association is basically loading the first available model it finds (I added a few checks in the sencha touch 2 code to prevent it from erroring out if the referred object is null or undefined, but this seems to have introduced this new bug for me.) I'm not sure if the Sencha team will get around to this, but I think a hasOne should be able to be null.

  7. #7
    Sencha User
    Join Date
    Jul 2010
    Posts
    51
    Vote Rating
    -1
    Answers
    1
    hdave is an unknown quantity at this point

      0  

    Default


    Has this been reported as a bug?

  8. #8
    Sencha Premium Member
    Join Date
    Mar 2012
    Location
    Westbrook, ME
    Posts
    117
    Vote Rating
    3
    sfpc2770 is on a distinguished road

      0  

    Default


    No bug that I'm aware of. Just acknowledgment that it's less than ideal. Sencha plans some major revamp of associations and related data package, but I don't know the specifics of it. Locally, we've created two new field types "model" and "store" that take a config object and parse the data as you would expect. It required some other extensions as well, including making sure the writer actually wrote those new types (as well as any association, which the current json writer does not). With all this in place, the code is nice and neat. A model is just a bunch of fields. Some are strings, some are dates, booleans, etc. And some are models or stores. -Sean

  9. #9
    Sencha User
    Join Date
    Mar 2011
    Posts
    150
    Vote Rating
    5
    Answers
    5
    incutonez is on a distinguished road

      2  

    Default


    FYI, this has been reported for Ext JS 4.2.1. Unfortunately, it looks like it's not fixed in 4.2.2, but it does look like it might be fixed in 5.0.0. What I currently do is a hack to see if the getter exists... you can use getAssociatedData and check if your function is in the object returned, or what I do is more direct and just do this['<hasOne namespace>'], where this is the scope of the model with a hasOne association.