Thank you for reporting this bug. We will make it our priority to review this report.
  1. #1
    Sencha User
    Join Date
    Dec 2008
    Location
    Lodz, Poland
    Posts
    173
    Vote Rating
    3
    grzegorz.borkowski is on a distinguished road

      0  

    Default [CLOSED][3.0.3] DataReader.realize expects all data sent to server to be returned

    [CLOSED][3.0.3] DataReader.realize expects all data sent to server to be returned


    I mentioned some reservations about REST support implemenation in the thread for Ext 3.0 RC2, many of which I see are fixed in 3.0.3. For example, the DataReader.update() no longer expects that server returns all or least some data with representation of the modified record. That's good. However, the DataReader.realize() is still broken. It still assumes that after creating the Record on the client, populating it with data, and sending this data to server, the server will send all this data back. But why server would do it? There is completely no point, it's only waste of bandwidth to send to the client the data that client already have. In some cases server can add/modify some of this data, then ok; but in many cases server won't. BUT, the realize method foolishly drops ALL local data and overrides it with data returned from server, see line 116 in DataReader:
    Code:
    rs.data = data;
    This approach makes no sense at all. The same bug was already fixed in update method, why it is not fixed in realize method?
    The only real difference is that in case of CREATE, in many cases the ID is generated by server, not by a client. So the realize method can expect the ID to be returned by the server in some cases. However, this ID doesn't have to be returned in response body. In RESTful services, it may be part of URL returned in Location header. So it's important to provide the extension point (per-class, i.e. to set it statically for all Ext.data.DataReader instances, and per-instance) for retrieving generated ID.
    To sum it up, two things should be done:
    1. Don't expect that server would return ANY data; in any case, don't throw away data already available on the client, instead override only those really returned by the server
    2. Provide easy to use extension points for retrieving generated ID from server response.

  2. #2
    Sencha User
    Join Date
    Dec 2008
    Location
    Lodz, Poland
    Posts
    173
    Vote Rating
    3
    grzegorz.borkowski is on a distinguished road

      0  

    Default


    I've just discovered that there are more problems with current code in Ext 3.0.3. Look into Ext.data.Api, in method restify(). There was an interceptor code added to this method.
    In the 3.0.3 code I downloaded, it looks like this:

    Code:
                // TODO: perhaps move this interceptor elsewhere?  like into DataProxy, perhaps?  Placed here
                // to satisfy initial 3.0 final release of REST features.
                proxy.onWrite = proxy.onWrite.createInterceptor(function(action, o, response, rs) {
                    var reader = o.reader;
                    var res = new Ext.data.Response({
                        action: action,
                        raw: response
                    });
    
                    switch (response.status) {
                    ....
    On the online docs, it looks like this:

    Code:
                // TODO: perhaps move this interceptor elsewhere?  like into DataProxy, perhaps?  Placed here
                // to satisfy initial 3.0 final release of REST features.
                proxy.onWrite = proxy.onWrite.createInterceptor(function(action, o, response, rs) {
                    var reader = o.reader;
                    var res = {};
                    switch (response.status) {
                    ...
    So the 'res' variable is initialized in different way. Which one is newer? hard to say. With the first code, in case of 204 response, I have later access to "real" response object stored under res.raw, so I can call res.raw.getResponseHeader('Location') to get access to response header. However, if response is 200, the res.raw will contain completely different object: the decoded JSON message (in case of JSON response) - that's how it is implemented in JsonReader. So what's the purpose of Ext.data.Response, and its "raw" attribute? If it is going to keep the response message instead of real response object, then how will I access response headers? And in case of second code snippet, I don't have access to response headers neither from 200 nor 204 responses.
    This is a huge mess, and should be fixed in future releases of Ext.

  3. #3
    Ext User
    Join Date
    Jan 2010
    Posts
    3
    Vote Rating
    0
    jmaasing is on a distinguished road

      0  

    Question Same type of problem in 3.1.1

    Same type of problem in 3.1.1


    I am also a bit confounded by the assumptions ExtJS makes. The REST framework I use does not return JSON data in the response to a POST. It does what the HTTP-spec allows and returns HTTP status 201 with the Location header set.

    Now, I have subclassed JsonReader and implemented the readResponse method to return a new Ext.data.Response. I parse the reponse header to get the ID of the new resource but the realize method contains :
    Code:
    if (data[f.name] !== f.defaultValue) {
       rs.data[f.name] = data[f.name];
    }
    Which will not behave itself since 'data' does not contain any response data, there simply is no response data to get apart from the ID. Which leads to realize overwriting the store record data with nothing (undefined).

    In my case I can get around it by doing something like:

    Code:
    if (data[f.name]) {
       if (data[f.name] !== f.defaultValue) {
         rs.data[f.name] = data[f.name];
       }
    }
    But still, the root of the problem is that ExtJS assumes too much of the behaviour of server side frameworks.

    Would be nice if the JsonReader could ease up on the assumption that the server returns data and maybe have a plugin or a subclass that could be used for server-sides that actually do return updated data in response to create (POST) request.

    Cheers,
    Johan

  4. #4
    Sencha - Sencha Touch Dev Team Jamie Avins's Avatar
    Join Date
    Mar 2007
    Location
    Redwood City, California
    Posts
    3,661
    Vote Rating
    21
    Jamie Avins is a jewel in the rough Jamie Avins is a jewel in the rough Jamie Avins is a jewel in the rough Jamie Avins is a jewel in the rough

      0  

    Default


    We are aware of the issue and a refactor is happening for a future release.

  5. #5
    Sencha User
    Join Date
    Jul 2009
    Posts
    9
    Vote Rating
    0
    amlody is on a distinguished road

      0  

    Default


    In 3.2 beta we still get responseText as raw instead of whole response:

    // instantiate response object
    var res = new Ext.data.Response({
    action: action,
    success: this.getSuccess(o),
    data: (root) ? this.extractData(root, false) : [],
    message: this.getMessage(o),
    raw: o
    });

    should be:
    raw: response