This is the last thing I have to do before I can send my beloved webapp into the wild, but of course IE7 is being difficult with me!!
I am using the JQuery Form plugin to upload data to my server. A servlet class will then run some operations with the file and shoot back some JSON to the client. As always, Chrome and Firefox handle the response like champs and give me the output I expect.
Internet Explorer 7 does not. I get an "Object Expected" error.... I have narrowed down my problem to a single function. I have made an educated guess that IE7 is not handling the response properly, but I really don't know. Here is the actual code that causes problems:
function uploadScript() {
$("#uploadScript").ajaxSubmit({
beforeSend: function() {
$("#uploadScript").attr("disabled", true);
},
dataType: "json",
cache: false,
success: function(response, status, xhr) {
if(response != undefined) {
commandArray = ([]).concat(response.command);
paramsArray = ([]).concat(response.params);
IDArray = ([]).concat(response.id);
commandID = response.commandID;
updateScriptView();
}
}
})
}
I have already tried explicitly setting the response header content type to 'application/json' to no avail. I have even read somewhere that such a header will even cause IE to bug out, so that front has certainly been confusing.
Perhaps it is the JSON syntax? Nope! I checked it, double checked it, then ran it through JSONLint just to be sure.
Any ideas on what I'm doing wrong?
EDIT: The JSON response literally is this:
{ "command" : ["sequential","wait","tune","endsequential"],"params" : [["5"],["00:00:03"],["202","RA29B[*]"],["100000"]],"id" : [100000,100002,100003,100001],"commandID" : 100004}
Eye-friendly is this:
{
"command": [
"sequential",
"wait",
"tune",
"endsequential"
],
"params": [
[
"5"
],
[
"00:00:03"
],
[
"202",
"RA29B[*]"
],
[
"100000"
]
],
"id": [
100000,
100002,
100003,
100001
],
"commandID": 100004
}
ANSWERED! Apparently, my $.attr() call in the beforeSend option of the ajaxSubmit() was causing problems in IE7. I do not know why this is the case, and my Googling yielded no results (Gotta Google the right question to get the right answer). Anyway, removing this code block solved my issue. I appreciate ALL the help that was given to me. Thanks guys!
Looks like you're using malsup plugin. If that's the case then the git repo has some known issues with this plugin:
https://github.com/malsup/form/issues
Check that your issue is not one already reported. Also check you jQuery version
this is the one for you: https://github.com/malsup/form/issues/179
Related
I have looked for a while for the answer to this, and I cannot figure it out. I'm not sure if it's actually possible.
Basically, I have a URL to a sound cloud search (https://soundcloud.com/search?q=rick%20astley%20never%20gonna%20give%20you%20up), and I'm wondering if it's possible to instantly play the top result or download the top result. Thank you in advanced!
So first its worth noting that Soundcloud has a Developers API, specifically a JavaScript SDK with Search functionality. They have documentation on how to do this.
However, I didn't want to go the registering App route for a lot of my projects. Although this might not be the recommended route, I'll add it as an answer anyways. If you look in the Network tab, you can see there are a bunch of requests and the one you really care about are the api-v2 related ones. You should find one that has something like this as a request URL:
https://api-v2.soundcloud.com/search?q=rick%20astley%20never%20gonna%20give%20you%20up&facet=model&client_id=OMITTED&limit=10&offset=0&linked_partitioning=1&app_version=OMITTED
This is the API request URL you Soundcloud makes behind the scenes specifically for its search API and you can see it passes in a bunch of GET parameters. I have OMITTED my specific credentials but as a user you have your own client_id and app_version so you'll need to simply put yours there.
If you want, you can manually go to this URL or just make a GET request to it via ajax and what gets returned back is a giant JSON like this:
And diving into it, you'll see there is a collection array property that has the results in it. Because you just want the first one, we can just look at the index in the array which comes out to be something like this:
{
"artwork_url": "https://i1.sndcdn.com/artworks-000074083588-q3fg6e-large.jpg",
"commentable": true,
"comment_count": 113,
"created_at": "2014-03-05T01:47:32Z",
"description": "",
"downloadable": true,
"download_count": 100,
"download_url": "https://api.soundcloud.com/tracks/137970300/download",
"duration": 266996,
"full_duration": 266996,
"embeddable_by": "all",
"genre": "Mashup",
"has_downloads_left": false,
"id": 137970300,
"kind": "track",
"label_name": "",
"last_modified": "2017-04-26T13:01:05Z",
"license": "all-rights-reserved",
"likes_count": 6307,
"permalink": "rick-astley-never-gonna-give",
"permalink_url": "https://soundcloud.com/andreasedstr-m/rick-astley-never-gonna-give",
"playback_count": 596829,
"public": true,
From here, you have two choices -- if you want, you can download it by looking at the property download_url or you can "play it". This part you might want to clarify what your definition of play is. You could just open the Soundcloud page and it should auto play I believe or you could embed it on your page and then somehow trigger a play. Whichever case, it's available.
To do this via JavaScript, you can probably just make a GET request to the URL above. I truncated the URL below. Remember you NEED to supply your client_id and app_version.
$.ajax({
method: 'GET',
url: 'https://api-v2.soundcloud.com/search?q=rick%20astley%20never%20gonna%20give%20you%20up',
dataType: 'json',
contentType: "application/json; charset=utf-8",
success: function (data) {
// do stuff here
// as mentioned because you care about the first index in the property above
// you would most likely interact with it by accessing data.collection[0]
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
One last thing if you run to CORS its because the service doesn't see you as an actual human. See here
Hope this helps.
I'm using the jQuery Datatables plugin to enable pagination, sorting and searching with my tables. The elements are showing up but not working, and the pagination only sometimes shows up. In Chrome console I'm getting the error:
Uncaught TypeError: Cannot use 'in' operator to search for 'length' in
Here is the demo page.
I'm using Bootstrap alongside this plugin.
That error is because of the method isArraylike in jQuery version 1.11.3. (only). The method looks like this
function isArraylike( obj ) {
// Support: iOS 8.2 (not reproducible in simulator)
// `in` check used to prevent JIT error (gh-2145)
// hasOwn isn't used here due to false negatives
// regarding Nodelist length in IE
var length = "length" in obj && obj.length, // <------ THIS IS THE CULPRIT
type = jQuery.type( obj );
.......
}
That version of jQuery was using "length" in object to get the length. (I do not know anything about it).
But I do know that no other versions of jquery have that issue.
The versions 1.11.3 and 2.1.4 (as James pointed out in the comments) have this issue.
So the solution would be to just upgrade to the next version or at least use any other version apart from 1.11.3 or 2.1.4
I'm working on Ruby on Rails with gem jquery-datatables-rails.
I update the gem directly from the last commit on GitHub:
gem 'jquery-datatables-rails', github: "rweng/jquery-datatables-rails", branch: "master"
This work for me, I suppose that that they will release soon a new version of the gem with this commit.
Upgrading to DataTables to DataTables 1.10.7 or 1.10.8-dev did not work for me (using jQuery 1.11.3).
Downgrading to jQuery 1.11.2 did work (using DataTables 10.0.0)
No need to downgrade jQuery.
I solved the same error by using aoColumns as
$('#id').DataTable( {
data: [["A", "B"], ["a", "b"]],
'aoColumns': [
{ sWidth: "50%", bSearchable: false, bSortable: false },
{ sWidth: "50%", bSearchable: false, bSortable: false }
],
} );
I am using jQuery 2.1.4 and DataTables 1.10.9
Whilst unrelated to DataTables, I came across this "cannot use in operator to search for length" error. This was the main Google result for the error so just wanted to post my issue as a response in case it helps anyone else.
I had:
ApplicationIDs: $.map(".application-checkbox:checked", function (checkedApplicationCheckbox, i) {
I'd forgotten to wrap my selector with the $ so the fix was to make sure I was passing the actual jQuery elements as the first argument to map and not just a string...
ApplicationIDs: $.map($(".application-checkbox:checked"), function (checkedApplicationCheckbox, i) {
I'm almost embarrased to post this ;)
Cheers
I fixed a similar issue by adding the json dataType like so:
$.ajax({
type: "POST",
url: "someUrl",
dataType: "json",
data: {
varname1 : "varvalue1",
varname2 : "varvalue2"
},
success: function (data) {
$.each(data, function (varname, varvalue){
...
});
}
});
And in my controller I had to use double quotes around any strings like so (note: they have to be escaped in java):
#RequestMapping(value = "/someUrl", method=RequestMethod.POST)
#ResponseBody
public String getJsonData(#RequestBody String parameters) {
// parameters = varname1=varvalue1&varname2=varvalue2
String exampleData = "{\"somename1\":\"somevalue1\",\"somename2\":\"somevalue2\"}";
return exampleData;
}
I had this exact same issue but jQuery version was not the culprit for me. In my case, I was incorrectly serializing the form. The code ended up with this error was:
$('#form_name').serialize()
Whereas I should have used.
$('#form_name').serializeArray()
I did this and my issue was resolved.
Just throwing out this little piece that I ignored. Could help someone out there.
With DataTables and calling a PHP-script with AJAX, be aware that you just must echo your array at the end. There is no need of encoding it first to a JSON object with json_encode.
So
header('Content-type:application/json;charset=utf-8');
echo $myArray // This will do. Do not use echo json_encode($myArray);
exit();
Otherwise you might end up with the dreadful error
Uncaught TypeError: Cannot use 'in' operator to search for 'length' in
or this one
Uncaught TypeError: Cannot read property 'length' of undefined
In my case the root cause of this error was due to invalid columns details passed in ajax data table calling.
$("#example1").DataTable({
searching: false,
paging: false,
serverSide: true,
ajax: {
url:"data-url",
type:"post",
data:{
key:"key_id"
}
},
columns: [
{"data":"column_1","name":"column_name_1"},
{"data":"EScore","name":"EScore"}
]
});
earlier i faced "Uncaught TypeError: Cannot use 'in' operator to search for 'length' when i was passing
columns: ["column_1","column_2"]
i resolved this by passing it with correct structure
columns: [
{"data":"column_1","name":"column_name_1"},
{"data":"EScore","name":"EScore"}
]
I have a problem with Datatables.
Until now, everything worked like a charm, now, from reasons unknown to me, datatables stopped working on my app.
My datatable ajax call is returning:
DataTables warning: table id=section-list - Invalid JSON response. For more information about this error, please see http://datatables.net/tn/1
My datatables init:
sections.find('table#section-list').dataTable({
"ajax": '/admin/page/get-section-list',
"columns": [
{"data": "SectionID"},
{"data": "SectionAlias"},
{"data": "Edit"},
{"data": "Delete"},
], aoColumnDefs: [
{
bSortable: false,
aTargets: [-1, -2, -3] // disable sorting on last three columns (icons)
}
]
});
and my page/get-section-list action
....
return new JsonModel(["data" => $sections]); // this is equivalent to echo json_encode() in basic php
I tested my JSON in Json Parser AND it is 100% ok and there is no previous output before this json.
Im using DataTables 1.10.3 with jQuery v1.10.2
I ran into a similar problem working with a data.json file and found the information from here very helpful. Specifically the recommendation to open chrome dev tools, click the network tab, and then try the request again so you can see it in the network timeline.
In my case it looked like the json file in my "ajax": '/path/to/data.json' was still being written to at the same time the reload request was trying to access the data. Adding a delay around the reload request to give data.json time to complete solved the issue:
setTimeout(
function() {
$('#tableid').DataTable().ajax.reload(null, false);
}, 125);
But its hard to know what the optimal delay setting should be. So instead of doing the settimeout() (which works btw), I changed how I was writing my data from nodejs asynchronous fs.writeFile() to the synchronous fs.writeFileSync() when writing to the file.
Every case will be a little different but if you know the data source normally returns valid json, you may want to inspect if that source is changing at the same time datatables is trying to access it.
I'm using the jQuery Form plugin to submit a form via AJAX and receive a JSON response:
$('#'+searchFormView.form.form.id).ajaxForm({
dataType:'json',
success:This.renderSearchResults,
error:This.error
});
The HTTP response body:
{
"grid":{
"headers":[
"Image","Additional","data","button"
],
"rows":[
["<img src=\"\Path_to_image\" alt=\"picture\">",
"Additonal",
"data",
"<button>Button text<\/button>"
],
[Some more of these arrays]
]
}
}
Chrome and FF are totally OK with this. It renders fine. IE strips the HTML out of the data value by the time it hits the success method:
renderSearchResults:function(data){
console.log(data.grid.rows[0][0]);
// Render the grid.
}
The result of the console log in IE:
Log:
If I watch the local variables while the success method runs:
"{
\"grid\":{
\"headers\":[
\"Image\",
\"Additional\",
\"data\",
\"Button\"
],
\"rows\":[
[\"\",\"Additional\",\"data\",\"Button text<\\/button>\"],
...
As you can see, the HTML tags are gone (curiously, the tag is still there).
Is this supposed to be an XSS protection?
How do I get around it?
Using ExtJS 2.2.1, I've got a container element which is supposed to load a piece of HTML from the server using:
autoLoad: { url: 'someurl' }
This works fine in Firefox, but for IE7 this results in a syntax error in ext-all-debug.js at line 7170:
this.decode = function(json){
return eval("(" + json + ')');
};
I fixed this by turning that function into this:
this.decode = function(json){
return eval('(function(){ return json; })()');
};
Then the autoLoad works well in both browsers, but then there's some odd bugs and besides, you really don't want to fix this in the ExtJS library as it will be unmaintainable (especially in the minified ext-all.js which is like half a megabye of Javascript on a single line).
I haven't been able to find a lot about this bug.
Variations that I've tried:
// With <script> tags around all the HTML
autoLoad: { url: 'someurl', scripts: true }
// With <script> tags around all the HTML
autoLoad: { url: 'someurl', scripts: false }
And visa versa without the <script> tags. There isn't any Javascript in the HTML either, but it should be possible, because eventually we will use Javascript inside the returned HTML.
The problem isn't in the HTML because even with the simplest possible HTML, the error is the same.
UPDATE - Response to donovan:
The simplest case where this is used is this one:
changeRolesForm = new Ext.Panel({
height: 600,
items: [{ autoScroll: true, autoLoad: WMS.Routing.Route("GetRolesList", "User") + '?userID=' + id}]
});
There is no datastore involved here. The response-type is also text\html, not json, so that can't be confusing it either. And as said, it's working just fine in Firefox, and in Firefox, it also executes the same eval function, but without the error. So it's not like Firefox follows a different path of execution, it's the same, but without the error on eval.
Check your JSON. FF allow trailing commas in JSON objects while IE does not. e.g.
{foo:'bar',baz:'boz',}
would work in FF but in IE it would throw a syntax error. In order for there to not be a syntax error the JSON would need to be:
{foo:'bar',baz:'boz'}
I located the source of the problem and it was indeed not with ExtJS. There was a section in the application that listened to the Ext.Ajax 'requestcomplete' event and tried decoding the response.responseText to json, even if the response was HTML (which it only is in one or two cases). IE was not amused by this.
If you're autoLoad'ing into a Panel or Element then a JSON decode shouldn't even be involved in the process. UpdateManager just defers to Ext.Element.update(..) which takes a string of html.
The only reason I can think that your response would be parsed as JSON is if you were using a JSONStore to request it - what are you using?
You should be able to do something simple like this:
var panel = new Ext.Panel({
autoLoad: 'someurl' // this is the short form, you can still use the object config
});
OR
var element = Ext.get('element id').update({
url: 'someurl'
});
Response to Update:
That looks correct as long as something weird isn't happening with the WMS.Routing.Route(...) method. I'm actually currently working on an ExtJS application myself so I was able to quickly test some different server responses and couldn't reproduce your problem. I've also relooked at the ExtJS 2.2.1 sources and still see nothing in the related Element update and UpdateManager that would make the call to Ext.util.JSON.decode(...) that you're seeing.
I'm imagining that its from an unrelated AJAX request in another part of your application. If you're not already, I would use firebug / firebug lite to help debug this - specifically try to get a stack trace to make sure the source of your problem really is this autoLoad.
I had the same problem, excuse my english, i'm from Mejico, i hope I can help… my problem was triggered when I submit a Form to login, my PHP returns a JSON with the response in case of failure like this:
$respuesta = "{success: false, msgError: 'El usuario o contraseña son incorrectos'}";
but I wasn't send a resposne when it success, well when it has a true success, then the ExtJS it was trying to decode my JSON response, but there was nothing to decode, i guess that was, in my case again, the problem… I solved just sending back a response for the true succes, FF, Chrome, Safari, dont catch the problem, but Opera and IE8 does… I hope I help someone, goodbye
I don't know what the problem is, but I wanted to point out that your "fix" makes it simply return the json as a string instead of an eval'd object, so of course there is no error anymore -- you removed the functionality. It could just as simply be:
this.decode = function(json){
return json;
}
Generally speaking, random errors like this do not usually indicate a bug in Ext, especially not in functions used as commonly as Ext.decode. I would guess that either there is something in the JSON that IE does not like that other browsers ignore, or more likely, there is something unexpected going on in your app that is not obvious from your description. Have you tried inspecting your request log in Firebug to see what the JSON actually looks like? Have you tried getting the result of your Route call into a variable first to verify its contents before populating the panel? Also, try setting the "break on all errors" option in Firebug to true -- a lot of times when you get a random function from Ext at the top of your stack trace, the culprit is actually some application code that you weren't expecting.