Jquery 1.9.1 version returning the response text as 'undefined' on success callback #95

Closed
karthilxg opened this Issue Apr 16, 2013 · 16 comments

Comments

Projects
None yet
9 participants
@karthilxg

Hi Folks,

I have been trying to use the mock ajax with jquery 1.9.1 version, the response is always returning as 'undefined' on the success callback but if I change the jquery earlier versions, say version less than 1.9 it works just fine. Is there any compatibility issues or I'm missing something. Please shed some light and check my sample code on the following link...

http://jsfiddle.net/karthilxg/SqZB5/5/

@dcneiner

This comment has been minimized.

Show comment
Hide comment
@dcneiner

dcneiner Apr 17, 2013

Collaborator

@karthilxg Thanks for this report, there definitely seems to be an issue with jQuery 1.9 – I tried running our tests against it and it is failing. Thank you for the report!

Collaborator

dcneiner commented Apr 17, 2013

@karthilxg Thanks for this report, there definitely seems to be an issue with jQuery 1.9 – I tried running our tests against it and it is failing. Thank you for the report!

@karthilxg

This comment has been minimized.

Show comment
Hide comment
@karthilxg

karthilxg Apr 18, 2013

@dcneiner If I send an stringified response instead of an JSON object, the mockajax function returns a response and works fine with jQuery 1.9.1 version. Please check the below fiddle.

http://jsfiddle.net/karthilxg/SqZB5/6/

Can I expect any fix for this issue ?

@dcneiner If I send an stringified response instead of an JSON object, the mockajax function returns a response and works fine with jQuery 1.9.1 version. Please check the below fiddle.

http://jsfiddle.net/karthilxg/SqZB5/6/

Can I expect any fix for this issue ?

@dcneiner

This comment has been minimized.

Show comment
Hide comment
@dcneiner

dcneiner Apr 20, 2013

Collaborator

Hey @karthilxg, I've been in Oxford at the jQuery UK conference and haven't looked at this further yet. Until I do, pull requests are welcome. Otherwise I'll be looking at this next week.

Collaborator

dcneiner commented Apr 20, 2013

Hey @karthilxg, I've been in Oxford at the jQuery UK conference and haven't looked at this further yet. Until I do, pull requests are welcome. Otherwise I'll be looking at this next week.

@jaboc83

This comment has been minimized.

Show comment
Hide comment
@jaboc83

jaboc83 Apr 23, 2013

Glanced through the new jQuery 1.9 code briefly and it looks like jQuery 1.9 made a change around line around line 8400 in the way it deals with response text that looks like it won't accept anything but a string anymore which makes sense according to the MDN XMLHttpRequest description

jQuery 1.8.3

// When requesting binary data, IE6-9 will throw an exception
// on any attempt to access responseText (#11426)
try {
   responses.text = xhr.responseText;
} catch( e ) {
}

Is Now:

jQuery 1.9

// When requesting binary data, IE6-9 will throw an exception
// on any attempt to access responseText (#11426)
if ( typeof xhr.responseText === "string" ) {
   responses.text = xhr.responseText;
}

Setting the dataType in your ajax options to 'json' can fix the problem as mockjax will auto-stringify the data for you assuming that you are intending to return json data.

$.mockjax({
    url: 'someUrl/path',
    data: { data:stuff },
    dataType: 'json',
    responseText: {
        success: true,
        mode: "Online"
    }
});

jaboc83 commented Apr 23, 2013

Glanced through the new jQuery 1.9 code briefly and it looks like jQuery 1.9 made a change around line around line 8400 in the way it deals with response text that looks like it won't accept anything but a string anymore which makes sense according to the MDN XMLHttpRequest description

jQuery 1.8.3

// When requesting binary data, IE6-9 will throw an exception
// on any attempt to access responseText (#11426)
try {
   responses.text = xhr.responseText;
} catch( e ) {
}

Is Now:

jQuery 1.9

// When requesting binary data, IE6-9 will throw an exception
// on any attempt to access responseText (#11426)
if ( typeof xhr.responseText === "string" ) {
   responses.text = xhr.responseText;
}

Setting the dataType in your ajax options to 'json' can fix the problem as mockjax will auto-stringify the data for you assuming that you are intending to return json data.

$.mockjax({
    url: 'someUrl/path',
    data: { data:stuff },
    dataType: 'json',
    responseText: {
        success: true,
        mode: "Online"
    }
});
@karthilxg

This comment has been minimized.

Show comment
Hide comment
@karthilxg

karthilxg Apr 23, 2013

Thanks for the suggestions, I'll try that.

Thanks for the suggestions, I'll try that.

@dangercris

This comment has been minimized.

Show comment
Hide comment
@dangercris

dangercris Apr 29, 2013

Try this change at line 101:

var jsonArray = JSON.parse(data);
$.each(jsonArray, $.proxy(function(index, item){

This was the solution for me :D

Try this change at line 101:

var jsonArray = JSON.parse(data);
$.each(jsonArray, $.proxy(function(index, item){

This was the solution for me :D

@karthilxg

This comment has been minimized.

Show comment
Hide comment
@karthilxg

karthilxg May 1, 2013

As @jaboc83 mentioned, I have tried by adding the dataType as 'json' in both my service and mockajax function and it works perfect in all jQuery versions. Thanks.

http://jsfiddle.net/karthilxg/dG7fk/1/

As @jaboc83 mentioned, I have tried by adding the dataType as 'json' in both my service and mockajax function and it works perfect in all jQuery versions. Thanks.

http://jsfiddle.net/karthilxg/dG7fk/1/

@karthilxg karthilxg closed this May 1, 2013

@orient-man

This comment has been minimized.

Show comment
Hide comment
@orient-man

orient-man Sep 30, 2013

I think it should be reopened. Sometimes setting dataType is not an option i.e. response type is conditional - look at this example:

http://jsfiddle.net/Lb4GG/

"Application" logic is as follows: if form is valid server returns JSON (click "Success' button), otherwise it returns back HTML with some attributes added (click "Failure" button). I think this logic is typical for many ASP.NET MVC apps with server side validation. I couldn't setup mock ajax to handle this situations and after upgrading to jQuery 2.0 my app works, but tests fail.

I think it should be reopened. Sometimes setting dataType is not an option i.e. response type is conditional - look at this example:

http://jsfiddle.net/Lb4GG/

"Application" logic is as follows: if form is valid server returns JSON (click "Success' button), otherwise it returns back HTML with some attributes added (click "Failure" button). I think this logic is typical for many ASP.NET MVC apps with server side validation. I couldn't setup mock ajax to handle this situations and after upgrading to jQuery 2.0 my app works, but tests fail.

@orient-man

This comment has been minimized.

Show comment
Hide comment
@orient-man

orient-man Sep 30, 2013

I "fixed it" with little hack:

https://gist.github.com/orient-man/cc14924bb31ec46462b5

jQuery uses getAllResponseHeaders to recognize response type, so I set "Content-Type" to JSON if responseText is object.

I "fixed it" with little hack:

https://gist.github.com/orient-man/cc14924bb31ec46462b5

jQuery uses getAllResponseHeaders to recognize response type, so I set "Content-Type" to JSON if responseText is object.

@dcneiner

This comment has been minimized.

Show comment
Hide comment
@dcneiner

dcneiner Oct 6, 2013

Collaborator

@orient-man Ok, I'll re-open and see what can be done. Your hack might prove less of a hack and more of a solution once we take a closer look :)

Collaborator

dcneiner commented Oct 6, 2013

@orient-man Ok, I'll re-open and see what can be done. Your hack might prove less of a hack and more of a solution once we take a closer look :)

@dcneiner dcneiner reopened this Oct 6, 2013

@markmhx

This comment has been minimized.

Show comment
Hide comment
@markmhx

markmhx Oct 29, 2013

An FYI for anyone getting undefined responses while using Deferred Objects with jQuery (http://api.jquery.com/deferred.then/) and the $.get() shorthand function (http://api.jquery.com/jQuery.get/):

If you don't set the dataType as "json" in the mockjax settings and switch away from the $.get() shorthand function to $.ajax() so you can set the request's dataType setting as "json" as well, you'll continue to get an undefined response even though mockjax is matching your request and attempting to fulfill it.

For example, mockjax will generate an undefined response is this case:

$.mockjax({
    url: '/example',
    dataType: 'json',
    responseText: {
        foo: 'bar'
    }
});

$.get('/example').then(
        function(response) {
                // response == undefined
        }
);

However, this will work:

$.mockjax({
    url: '/example',
    dataType: 'json',
    responseText: {
        foo: 'bar'
    }
});

$.ajax({ url: '/example', dataType: 'json' }).then(
        function(response) {
                // response == { foo: 'bar' }
        }
);

I'm not aware of how you'd otherwise tell $.get() in the Deferred Objects way of things to use a particular dataType, which appears to be a shortcoming of the $.get() method.

markmhx commented Oct 29, 2013

An FYI for anyone getting undefined responses while using Deferred Objects with jQuery (http://api.jquery.com/deferred.then/) and the $.get() shorthand function (http://api.jquery.com/jQuery.get/):

If you don't set the dataType as "json" in the mockjax settings and switch away from the $.get() shorthand function to $.ajax() so you can set the request's dataType setting as "json" as well, you'll continue to get an undefined response even though mockjax is matching your request and attempting to fulfill it.

For example, mockjax will generate an undefined response is this case:

$.mockjax({
    url: '/example',
    dataType: 'json',
    responseText: {
        foo: 'bar'
    }
});

$.get('/example').then(
        function(response) {
                // response == undefined
        }
);

However, this will work:

$.mockjax({
    url: '/example',
    dataType: 'json',
    responseText: {
        foo: 'bar'
    }
});

$.ajax({ url: '/example', dataType: 'json' }).then(
        function(response) {
                // response == { foo: 'bar' }
        }
);

I'm not aware of how you'd otherwise tell $.get() in the Deferred Objects way of things to use a particular dataType, which appears to be a shortcoming of the $.get() method.

@dcneiner

This comment has been minimized.

Show comment
Hide comment
@dcneiner

dcneiner Oct 30, 2013

Collaborator

@markmhx In your particular case, can you not just use $.getJSON instead of $.get?

Collaborator

dcneiner commented Oct 30, 2013

@markmhx In your particular case, can you not just use $.getJSON instead of $.get?

@markmhx

This comment has been minimized.

Show comment
Hide comment
@markmhx

markmhx Nov 2, 2013

@dcneiner Yep, that works too!

As a suggestion, perhaps it would be better if mockjax simply did not match an Ajax request created by $.get in this scenario at all instead of simply providing a null response object to its success method? That would seem to minimize confusion since otherwise it appears to half work.

Or perhaps a notice of sorts could be thrown in the console to indicate how the JSON datatype isn't supported without modifying the ajax function call.

Either of these may be overkill, but they favor eliminating possible confusion for new users who may not get configuration right off the bat.

markmhx commented Nov 2, 2013

@dcneiner Yep, that works too!

As a suggestion, perhaps it would be better if mockjax simply did not match an Ajax request created by $.get in this scenario at all instead of simply providing a null response object to its success method? That would seem to minimize confusion since otherwise it appears to half work.

Or perhaps a notice of sorts could be thrown in the console to indicate how the JSON datatype isn't supported without modifying the ajax function call.

Either of these may be overkill, but they favor eliminating possible confusion for new users who may not get configuration right off the bat.

@AlexKeySmith

This comment has been minimized.

Show comment
Hide comment
@AlexKeySmith

AlexKeySmith Mar 17, 2014

I'd very much like to see some sort of console warning or perhaps a warning in the documentation - as I fell over this and it's very tricky to diagnose.

I'd very much like to see some sort of console warning or perhaps a warning in the documentation - as I fell over this and it's very tricky to diagnose.

@jcreamer898

This comment has been minimized.

Show comment
Hide comment
@jcreamer898

jcreamer898 May 20, 2014

Collaborator

FWIW, I also fixed this with just wrapping my responseText object in JSON.stringify

Collaborator

jcreamer898 commented May 20, 2014

FWIW, I also fixed this with just wrapping my responseText object in JSON.stringify

@jakerella jakerella added this to the Mockjax 1.6.0 milestone Aug 14, 2014

@jakerella

This comment has been minimized.

Show comment
Hide comment
@jakerella

jakerella Sep 30, 2014

Owner

@orient-man It looks like your patch is working for now... I'm integrating it now and testing. Hopefully this bug will be resolved in 1.6.0

Owner

jakerella commented Sep 30, 2014

@orient-man It looks like your patch is working for now... I'm integrating it now and testing. Hopefully this bug will be resolved in 1.6.0

@jakerella jakerella closed this in 0a0e1a0 Sep 30, 2014

jakerella added a commit that referenced this issue Sep 30, 2014

Merge pull request #177 from appendto/95-undefined-responseText
Fixed #95: undefined responseText in success method with no dataType
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment