139

jQuery v1.7.2

I have this function that is giving me the following error while executing :

Uncaught TypeError: Illegal invocation

Here's the function :

$('form[name="twp-tool-distance-form"]').on('submit', function(e) {
    e.preventDefault();
    
    var from = $('form[name="twp-tool-distance-form"] input[name="from"]');
    var to = $('form[name="twp-tool-distance-form"] input[name="to"]');
    var unit = $('form[name="twp-tool-distance-form"] input[name="unit"]');
    var speed = game.unit.speed($(unit).val());
    
    if (!/^\d{3}\|\d{3}$/.test($(from).val()))
    {
        $(from).css('border-color', 'red');
        return false;
    }
    
    if (!/^\d{3}\|\d{3}$/.test($(to).val()))
    {
        $(to).css('border-color', 'red');
        return false;
    }
    
    var data = {
        from : from,
        to : to,
        speed : speed
    };
    
    $.ajax({
        url : base_url+'index.php',
        type: 'POST',
        dataType: 'json',
        data: data,
        cache : false
    }).done(function(response) {
        alert(response);
    });
    
    return false;
});

If I remove data from the ajax call, it works! .. Any suggestions?

Thanks!

Martlark
  • 14,208
  • 13
  • 83
  • 99
yoda
  • 10,834
  • 19
  • 64
  • 92

11 Answers11

154

Try to set processData: false in ajax settings like this

$.ajax({
    url : base_url+'index.php',
    type: 'POST',
    dataType: 'json',
    data: data,
    cache : false,
    processData: false
}).done(function(response) {
    alert(response);
});
Justo
  • 1,793
  • 1
  • 10
  • 6
  • 13
    `By default, data passed in to the data option as an object (technically, anything other than a string) will be processed and transformed into a query string, fitting to the default content-type "application/x-www-form-urlencoded". If you want to send a DOMDocument, or other non-processed data, set this option to false.` – Tilak Raj Apr 12 '16 at 21:34
  • 5
    You may also need to add `contentType: false` . I did when uploading a file. See https://stackoverflow.com/questions/21044798/how-to-use-formdata-for-ajax-file-upload – khylo Mar 05 '20 at 12:44
  • In my case contentType: false worked. please try if any one facing after using the above answer – Soubhagya Kumar Barik Jun 10 '22 at 12:41
  • Is $ajax better or fetch API? I know fetch API is preferred for modern browsers – Partha Mandayam Aug 09 '23 at 06:48
  • why should we set contenttype false – Partha Mandayam Aug 09 '23 at 06:49
  • can you give example of how the data is transformed into a query string? – Partha Mandayam Aug 09 '23 at 06:56
  • I'm just passing a file object in ajax call to a procedure which stores that file object in a session variable to be referenced later in page_load. do I need to set contenttype and processdata to false – Partha Mandayam Aug 09 '23 at 06:59
126

I think you need to have strings as the data values. It's likely something internally within jQuery that isn't encoding/serializing correctly the To & From Objects.

Try:

var data = {
    from : from.val(),
    to : to.val(),
    speed : speed
};

Notice also on the lines:

$(from).css(...
$(to).css(

You don't need the jQuery wrapper as To & From are already jQuery objects.

KaraKaplanKhan
  • 734
  • 1
  • 14
  • 31
LessQuesar
  • 3,123
  • 1
  • 21
  • 29
  • 3
    Thanks, forgot I had loaded objects instead of strings, usually I load strings :) – yoda Apr 25 '12 at 22:31
  • 3
    This approach helps me. I name my variables as `$from = $('#from');` This helps me remember that it represents a jQuery object which helps avoid calling a method on something that's a string or trying to manipulate a string with `.toString()` or something when it's a jQuery object. – timbrown Apr 16 '13 at 15:13
  • I had the `.val()` part missing, so it wasn't passing the value. – SharpC Oct 23 '15 at 13:41
23

Just for the record it can also happen if you try to use undeclared variable in data like

var layout = {};
$.ajax({
  ...
  data: {
    layout: laoyut // notice misspelled variable name
  },
  ...
});
Ivan Ivanic
  • 2,982
  • 1
  • 20
  • 21
21

If you want to submit a form using Javascript FormData API with uploading files you need to set below two options:

processData: false,
contentType: false

You can try as follows:

//Ajax Form Submission
$(document).on("click", ".afs", function (e) {
    e.preventDefault();
    e.stopPropagation();
    var thisBtn = $(this);
    var thisForm = thisBtn.closest("form");
    var formData = new FormData(thisForm[0]);
    //var formData = thisForm.serializeArray();

    $.ajax({
        type: "POST",
        url: "<?=base_url();?>assignment/createAssignment",
        data: formData,
        processData: false,
        contentType: false,
        success:function(data){
            if(data=='yes')
            {
                alert('Success! Record inserted successfully');
            }
            else if(data=='no')
            {
                alert('Error! Record not inserted successfully')
            }
            else
            {
                alert('Error! Try again');
            }
        }
    });
});
Bablu Ahmed
  • 4,412
  • 5
  • 49
  • 64
6

In my case, I just changed

Note: This is in case of Django, so I added csrftoken. In your case, you may not need it.

Added contentType: false, processData: false

Commented out "Content-Type": "application/json"

$.ajax({
    url: location.pathname, 
    type: "POST",
    crossDomain: true,
    dataType: "json",
    headers: {
        "X-CSRFToken": csrftoken,
        "Content-Type": "application/json"
    },
    data:formData,
    success: (response, textStatus, jQxhr) => {

    },
    error: (jQxhr, textStatus, errorThrown) => {

    }
})

to

$.ajax({
    url: location.pathname, 
    type: "POST",
    crossDomain: true,
    dataType: "json",
    contentType: false,
    processData: false,
    headers: {
        "X-CSRFToken": csrftoken
        // "Content-Type": "application/json",
    },
    data:formData,
    success: (response, textStatus, jQxhr) => {

    },
    error: (jQxhr, textStatus, errorThrown) => {

    }
})

and it worked.

hygull
  • 8,464
  • 2
  • 43
  • 52
5

In My case I have't define all variables which I am passing to data in ajax.

var page = 1;

$.ajax({
    url: 'your_url',
    type: "post",
    data: { 'page' : page, 'search_candidate' : search_candidate }
    success: function(result){
        alert('function called');
    }
)}

I have just defined variable var search_candidate = "candidate name"; and its working.

var page = 1;
var search_candidate = "candidate name"; // defined
$.ajax({
    url: 'your_url',
    type: "post",
    data: { 'page' : page, 'search_candidate' : search_candidate }
    success: function(result){
        alert('function called');
    }
)}
  • I had incorrectly passed in value to the data object that was not convertible to an allowable value. A model instance. – Martlark Jun 12 '23 at 22:15
2

Working for me. processData: false, contentType: false, is required for working.

 var formData = new FormData($('#author_post')[0]);
 formData.append('t','author-add');
 $.ajax({
        type: 'POST',
        url: 'url-here',
        cache: false,
        processData: false,
        contentType: false,
        data:formData,
        success: function(response) {
           //success code
        }
 });
Rana Nadeem
  • 1,115
  • 1
  • 9
  • 17
1

Also this is a cause too: If you built a jQuery collection (via .map() or something similar) then you shouldn't use this collection in .ajax()'s data. Because it's still a jQuery object, not plain JavaScript Array. You should use .get() at the and to get plain js array and should use it on the data setting on .ajax().

Burak TARHANLI
  • 190
  • 2
  • 8
1

Here is some working sample code:

let formData = new FormData($("#formId")[0]);
 
$.ajax({
  url: "/api/v1/save-data",
  type: "POST",
  enctype: "multipart/form-data",
  dataType: "json",
  data: formData,
  success: function(data) {
    console.log(data);
  },
  cache: false,
  contentType: false,
  processData: false,
  error: function() {
    console.log("Error");
  }
});
Aaron Meese
  • 1,670
  • 3
  • 22
  • 32
MrAwanish
  • 11
  • 3
0

My problem was unrelated to processData. It was because I sent a function that cannot be called later with apply because it did not have enough arguments. Specifically I shouldn't have used alert as the error callback.

$.ajax({
    url: csvApi,
    success: parseCsvs,
    dataType: "json",
    timeout: 5000,
    processData: false,
    error: alert
});

See this answer for more information on why that can be a problem: Why are certain function calls termed "illegal invocations" in JavaScript?

The way I was able to discover this was by adding a console.log(list[ firingIndex ]) to jQuery so I could track what it was firing.

This was the fix:

function myError(jqx, textStatus, errStr) {
    alert(errStr);
}

$.ajax({
    url: csvApi,
    success: parseCsvs,
    dataType: "json",
    timeout: 5000,
    error: myError // Note that passing `alert` instead can cause a "jquery.js:3189 Uncaught TypeError: Illegal invocation" sometimes
});
Community
  • 1
  • 1
ubershmekel
  • 11,864
  • 10
  • 72
  • 89
0

The problem here is that you pass an input object as data to ajax like this :

$('form[name="twp-tool-distance-form"] input[name="from"]')

So you have to pass the input value just like this:

$('form[name="twp-tool-distance-form"] input[name="from"]').val()
Amolgorithm
  • 697
  • 2
  • 20