4

Alright, working on getting amplify decoders. Strange issue. If I have a beforeSend attached to my request, the decoder does not fire. remove the beforeSend and the decoder fires.

Here are the two examples.

  1. With no beforeSend.

http://jsfiddle.net/sujesharukil/Td2P4/12/

  1. With beforeSend

http://jsfiddle.net/sujesharukil/Td2P4/14/

Can someone tell me what is happening? why wouldnt the decoder work if I have a beforeSend? I am assuming the decoder should fire after the request is received, so beforeSend should not have any impact on it!

note: stackoverflow wants me to post code here, not just fiddles

//please check the fiddles

amplify.request({
    resourceId: "testRequest",
    data: {
        json: JSON.stringify({
            text: 'hello world'
        })
    },
    success: function(data, status) {
        console.log(data, status);
        $('.messages').append('<div> text retrieved: ' + data.text + '</div>');
    },
    error: function(status, xhr) {
        console.log(xhr);
    }
});​

Help?

-Suj

Sujesh Arukil
  • 2,469
  • 16
  • 37

2 Answers2

9

Ok, figured it out.

in amplifyjs this section caught my eye

beforeSend : function( _xhr, _ajaxSettings ) {

                xhr = _xhr;
                ajaxSettings = _ajaxSettings;
                var ret = defnSettings.beforeSend ?
                    defnSettings.beforeSend.call( this, ampXHR, ajaxSettings ) : true;
                return ret && amplify.publish( "request.before.ajax",
                    defnSettings, settings, ajaxSettings, ampXHR );
            }
        });

note that, it will call beforeSend if it is specified, else set var ret is set to true

if set to true, it will then publish "request.before.ajax"

way down in the file, amplify listens for this message

amplify.subscribe( "request.before.ajax", function( resource, settings, ajaxSettings, ampXHR ) {
var _success = ampXHR.success,
    _error = ampXHR.error,
    decoder = $.isFunction( resource.decoder )
        ? resource.decoder
        : resource.decoder in amplify.request.decoders
            ? amplify.request.decoders[ resource.decoder ]
            : amplify.request.decoders._default;

if ( !decoder ) {
    return;
}

function success( data, status ) {
    _success( data, status );
}
function error( data, status ) {
    _error( data, status );
}
ampXHR.success = function( data, status ) {
    decoder( data, status, ampXHR, success, error );
};
ampXHR.error = function( data, status ) {
    decoder( data, status, ampXHR, success, error );
};

});

so, if you have a beforeSend and if it does not return true, the message is never published and the decoders are never hit!

the solution?

return true from your beforeSend function

amplify.request.define("testRequest", "ajax", {

url: "/echo/json/",
dataType: 'json',
type: 'POST',
decoder: function(data, status, xhr, success, error) {
    console.log('decoder fired');
    $('.messages').append('<div>decoder fired </div>');
    success(data);
},
beforeSend: function(xhr){
//not doing anything here, just logging;
    console.log('before send fired');
    $('.messages').append('<div>before send fired </div>');
    return true; //this is the key
}

});

works like a charm! Hope this helps someone else trying to figure this out!

Sujesh Arukil
  • 2,469
  • 16
  • 37
  • This did help me out, thanks. In my case, I was trying to define a custom cache, ran into this same issue. Couldn't find any documentation covering this. Appreciate your posting your research! – Soulriser Nov 29 '14 at 17:28
0

Just copied this from the example pages. Hope it helps.

amplify.request.decoders.appEnvelope =
    function ( data, status, xhr, success, error ) {
        if ( data.status === "success" ) {
            success( data.data );
        } else if ( data.status === "fail" || data.status === "error" ) {
            error( data.message, data.status );
        } else {
            error( data.message , "fatal" );
        }
    };

amplify.request.define( "decoderExample", "ajax", {
    url: "/myAjaxUrl",
    type: "POST",
    decoder: "appEnvelope" // <--- a function name(string) and not a function.
});

amplify.request({
    resourceId: "decoderExample",
    success: function( data ) {
        data.foo; // bar
    },
    error: function( message, level ) {
        alert( "always handle errors with alerts." );
    }
});
Stefan
  • 5,644
  • 4
  • 24
  • 31
  • Thank you Stefan for that response. my stuff is also from their docs and as I said, it all works great except when there is a beforeSend in the request. that is where it does not fire the decoder. So no, your response does not help. :( – Sujesh Arukil Nov 09 '12 at 18:09