mikehostetler / amplify

AmplifyJS
http://amplifyjs.com
GNU General Public License v2.0
1.45k stars 143 forks source link

Can not set both decoder and beforeSend #76

Open ghost opened 11 years ago

ghost commented 11 years ago

Errors from json calls are not returned, so the documentation suggests using a decoder. However if I set both decoder and beforeSend in the getSettings variable below the decoder won't be invoked on error. If I set only the decoder, it will be invoked on error.

define('repository', ['amplify'], function (amplify) {

    var repo = function (baseUrl, resourceName) {

        this.list = function (callback, args) {
            return amplify.request({
                resourceId: resourceName,
                data: args,
                success: callback.success,
                error: callback.error
            });
        };

        var setUserToken = function (jqXhr, settings) {
            jqXhr.setRequestHeader("X-UserToken", amplify.store("userToken"));
        };

        amplify.request.decoders.appEnvelope =
                    function (data, status, xhr, success, error) {
                        if (status === "success") {
                            success(data);
                        } else {
                            try {
                                var message = JSON.parse(xhr.responseText);
                                error(status, message.message);
                            } catch (e) {
                                error(status, xhr.responseText);
                            }
                        }
                    }

        var getSettings = {
            url: baseUrl,
            dataType: 'json',
            type: 'GET',
            beforeSend: setUserToken, // This must be commented out or the decoder won't be invoked
            decoder: "appEnvelope"
        };

        amplify.request.define(resourceName, "ajax", getSettings);
    };

    return {
        Repository: repo
    };
});
elijahmanor commented 11 years ago

You found an interesting scenario, congratulations ;) But seriously, sorry for the inconvenience. I converted your code snippet into a jsFiddle http://jsfiddle.net/yUs2S/ and tracked down the issue.

Thankfully there is an easy workaround until we get something in place that takes care of the real problem. You can return true; as the last statement in your setUserToken function and all should work as expected.

_Elijah Manor _Senior Architect & Trainer for appendTo http://appendto.com Microsoft Regional Director & Microsoft ASP.NET MVPhttps://mvp.support.microsoft.com/profile=EEFEC54D-1659-4C89-8423-5370865C8342

ASPInsider http://aspinsiders.com/default.aspx My profiles: [image: Blogger] http://elijahmanor.com[image: Twitter]http://twitter.com/elijahmanor[image: Facebook] http://www.facebook.com/elijahmanor[image: LinkedIn]http://www.linkedin.com/in/elijahmanor[image: Delicious] http://delicious.com/elijahmanor

On Thu, Dec 6, 2012 at 6:16 AM, jfitzharris notifications@github.comwrote:

Errors from json calls are not returned, so the documentation suggests using a decoder. However if I set both decoder and beforeSend in the getSettings variable below the decoder won't be invoked on error. If I set only the decoder, it will be invoked on error.

define('repository', ['amplify'], function (amplify) {

var repo = function (baseUrl, resourceName) {

    this.list = function (callback, args) {
        return amplify.request({
            resourceId: resourceName,
            data: args,
            success: callback.success,
            error: callback.error
        });
    };

    var setUserToken = function (jqXhr, settings) {
        jqXhr.setRequestHeader("X-UserToken", amplify.store("userToken"));
    };

    amplify.request.decoders.appEnvelope =
                function (data, status, xhr, success, error) {
                    if (status === "success") {
                        success(data);
                    } else {
                        try {
                            var message = JSON.parse(xhr.responseText);
                            error(status, message.message);
                        } catch (e) {
                            error(status, xhr.responseText);
                        }
                    }
                }

    var getSettings = {
        url: baseUrl,
        dataType: 'json',
        type: 'GET',
        beforeSend: setUserToken, // This must be commented out or the decoder won't be invoked
        decoder: "appEnvelope"
    };

    amplify.request.define(resourceName, "ajax", getSettings);
};

return {
    Repository: repo
};});

— Reply to this email directly or view it on GitHubhttps://github.com/appendto/amplify/issues/76.

ghost commented 11 years ago

Thanks for the workaround, it solves our problem.

ghost commented 11 years ago

I am reopening this issue as I have found another problem. In the setUserToken function, add another call to jqXhr.setRequestHeader to add another header and run. Amplify will return an error status but there is no error message. Looking in Fiddler I don't see the ajax call being made, so I wonder if Amplify has a problem with multiple request headers.

CFWinsor commented 10 years ago

I am finding that I have this issue using amplify 1.1.2 and adding the return true; at the end of my beforeBind function as you described does not solve the problem. If beforeBind is uncommented it doesn't go through the decoder function, if it is commented out then it does. Is there an update on this problem? My code is basically identical to that used by jfitzharris above.