Results 1 to 3 of 3

Thread: Ext.data.Model.save Returning Associated Data Does Not Update Associated Data

    You found a bug! We've classified it as EXTJS-8822 . We encourage you to continue the discussion and to find an acceptable workaround while we work on a permanent fix.
  1. #1
    Sencha User
    Join Date
    May 2013
    Posts
    48
    Vote Rating
    1
      0  

    Default Ext.data.Model.save Returning Associated Data Does Not Update Associated Data

    Hello Extjs & Sencha,

    I wrote about this a while back on extjs 4.1, however that patch no longer applies to extjs 6.

    Using Extjs 6.0.0.640

    Create a Model on the client and save it. On the return from the save (POST) include the associated data for the model. The models associated data stores are created but the data itself is not included on the model.

    My temporary fix is provided below

    Post
    Code:
    POST: 
    { 
      id: 5, 
      travelTypeId: 6, 
      paymentTypeId: 3
    }
    Return
    Code:
    Data: 
    { 
      id: 5, 
      travelTypeId: 6, 
      travelType: 
      { 
           id: 6, 
           name: 'International' 
      }, 
      paymentTypeId: 3, 
      paymentType: 
      { 
           id: 3, 
           name: 'Visa' 
      }
    }
    model.getTravelType() =
    Code:
    {
       id: 0,
       name: ''
    }
    Reference to my 4.1 case.
    https://www.sencha.com/forum/showthr...ample-Provided

  2. #2
    Sencha User
    Join Date
    May 2013
    Posts
    48
    Vote Rating
    1
      1  

    Default

    And this fix as provided. Be warned it was not extensively tested at this point

    Code:
    
    Ext.define('Frozen.hotfix.model.create', {
        override: 'Ext.data.Model',
        save: function (options) {
            options = Ext.apply({}, options);
    
    
            var me = this,
                phantom = me.phantom,
                dropped = me.dropped,
                action = dropped ? 'destroy' : (phantom ? 'create' : 'update'),
                scope = options.scope || me,
                callback = options.callback,
                proxy = me.getProxy(),
                operation;
    
    
            options.records = [me];
            options.internalCallback = function (operation) {
                var args = [me, operation],
                    success = operation.wasSuccessful();
                if (success) {
                    Ext.callback(options.success, scope, args);
                } else {
                    Ext.callback(options.failure, scope, args);
                }
                args.push(success);
                Ext.callback(callback, scope, args);
            };
            delete options.callback;
    
    
            options.recordCreator = function (data, type, readOptions) {
                // Important to change this here, because we might be loading associations,
                // so we do not want this to propagate down. If we have a session, use that
                // so that we end up getting the same record. Otherwise, just remove it.
                var session = me.session;
                if (readOptions) {
                    readOptions.recordCreator = session ? session.recordCreator : null;
                }
                me.set(data, me._commitOptions);
                // Do the id check after set since converters may have run
                //if (doIdCheck && me.getId() !== id) {
                //    Ext.raise('Invalid record id returned for ' + id + '@' + me.entityName);
                //}
                return me;
            };
    
    
            operation = proxy.createOperation(action, options);
    
    
            // Not a phantom, then we must perform this operation on the remote datasource.
            // Record will be removed from the store in the callback upon a success response
            if (dropped && phantom) {
                // If it's a phantom, then call the callback directly with a dummy successful ResultSet
                operation.setResultSet(Ext.data.reader.Reader.prototype.nullResultSet);
                me.setErased();
                operation.setSuccessful(true);
            } else {
                operation.execute();
            }
            return operation;
        },
    });
    Code:
    
    Ext.define('Frozen.hotfix.process', {
        override: 'Ext.data.operation.Operation',
        doProcess: function (resultSet, request, response) {
            var me = this,
                commitSetOptions = me._commitSetOptions,
                clientRecords = me.getRecords(),
                clientLen = clientRecords.length,
                clientIdProperty = clientRecords[0].clientIdProperty,
                serverRecords = resultSet.getRecords(),
                // a data array, not records yet
                serverLen = serverRecords ? serverRecords.length : 0,
                clientMap, serverRecord, clientRecord, i;
            if (serverLen && clientIdProperty) {
                // Linear pass over clientRecords to map them by their idProperty
                clientMap = Ext.Array.toValueMap(clientRecords, 'id');
                // Linear pass over serverRecords to match them by clientIdProperty to the
                // corresponding clientRecord (if one exists).
                for (i = 0; i < serverLen; ++i) {
                    serverRecord = serverRecords[i];
                    clientRecord = clientMap[serverRecord[clientIdProperty]];
                    if (clientRecord) {
                        // Remove this one so we don't commit() on it next
                        delete clientMap[clientRecord.id];
                        // Remove the clientIdProperty value since we don't want to store it
                        delete serverRecord[clientIdProperty];
                        clientRecord.set(serverRecord, commitSetOptions);
                    } else // set & commit
                    {
                        Ext.log.warn('Ignoring server record: ' + Ext.encode(serverRecord));
                    }
                }
                // Linear pass over any remaining client records.
                for (i in clientMap) {
                    clientMap[i].commit();
                }
            } else {
                // Either no serverRecords or no clientIdProperty, so index correspondence is
                // all we have to go on. If there is no serverRecord at a given index we just
                // commit() the record.
                for (i = 0; i < clientLen; ++i) {
                    clientRecord = clientRecords[i];
                    if (serverLen === 0 || !(serverRecord = serverRecords[i]) || serverRecord.isModel) {
                        // once i > serverLen then serverRecords[i] will be undefined...
                        clientRecord.commit();
                    } else {
                        clientRecord.set(serverRecord, commitSetOptions);
                    }
                }
            }
        },
    });

  3. #3
    Sencha Premium User
    Join Date
    Feb 2012
    Posts
    68
    Vote Rating
    44
      0  

    Default

    Still an issue in 6.5.2

Similar Threads

  1. Why model.save() Does not update associated data?
    By albrogor in forum Ext 5: Q&A
    Replies: 2
    Last Post: 9 Mar 2015, 11:57 PM
  2. Replies: 12
    Last Post: 21 Apr 2013, 12:54 AM
  3. Sencha touch model.load(id,..) returning cached model data with id requested
    By karencc in forum Sencha Touch 2.x: Discussion
    Replies: 2
    Last Post: 13 Mar 2013, 8:55 PM
  4. Replies: 1
    Last Post: 25 Feb 2013, 11:36 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •