jQuery - invocação ilegal

107

jQuery v1.7.2

Tenho esta função que está me dando o seguinte erro durante a execução:

Uncaught TypeError: Illegal invocation

Esta é a função:

$('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;
});

Se eu remover datade uma chamada de ajax, funciona .. alguma sugestão?

Obrigado!

yoda
fonte
tente remover fromdos dados. Talvez esteja em conflito com jquery de
gopi1410
6
Você percebe que está tentando empurrar objetos jQuery, não JSON, certo?
advogado de
18
Acontece comigo regularmente quando eu esqueço o .val () em algum objeto jQuery ...
userfuser

Respostas:

117

Acho que você precisa ter strings como valores de dados. Provavelmente é algo internamente no jQuery que não está codificando / serializando corretamente os objetos To & From.

Experimentar:

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

Observe também nas linhas:

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

Você não precisa do wrapper jQuery, pois To & From já são objetos jQuery.

LessQuesar
fonte
2
Obrigado, esqueci que tinha carregado objetos em vez de strings, normalmente eu carrego strings :)
yoda
3
Essa abordagem me ajuda. Chamo minhas variáveis ​​de. $from = $('#from');Isso me ajuda a lembrar que representa um objeto jQuery que ajuda a evitar chamar um método em algo que é uma string ou tentar manipular uma string com .toString()ou algo quando é um objeto jQuery.
timbrown
Estava .val()faltando a parte, então não estava passando o valor.
SharpC
109

Tente definir processData: false em configurações ajax como esta

$.ajax({
    url : base_url+'index.php',
    type: 'POST',
    dataType: 'json',
    data: data,
    cache : false,
    processData: false
}).done(function(response) {
    alert(response);
});
Justo
fonte
8
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.
BOTJr.
Você também pode precisar adicionar contentType: false. Eu fiz ao enviar um arquivo. Vejo stackoverflow.com/questions/21044798/…
khylo
18

Só para registro, também pode acontecer se você tentar usar uma variável não declarada em dados como

var layout = {};
$.ajax({
  ...
  data: {
    layout: laoyut // notice misspelled variable name
  },
  ...
});
Ivan Ivanić
fonte
1
Obrigado por isso !! Isso era totalmente onde eu estava sendo bloqueado.
Matt Zelenak
13

Se você deseja enviar um formulário usando a API Javascript FormData com upload de arquivos, você precisa definir as duas opções a seguir:

processData: false,
contentType: false

Você pode tentar o seguinte:

//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
fonte
O que essas duas opções fazem, você poderia explicar?
rahim.nagori
2

No meu caso, eu apenas mudei

Nota: Este é o caso do Django, então eu adicionei csrftoken. No seu caso, pode não ser necessário.

Adicionado contentType: false,processData: false

Comentado "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) => {

    }
})

para

$.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) => {

    }
})

e funcionou.

higiênico
fonte
2

No meu caso, não defini todas as variáveis ​​que estou passando para os dados no ajax.

var page = 1;

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

Acabei de definir a variável var search_candidate = "candidate name";e seu funcionamento.

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');
    }
)}
Rajesh Kharatmol
fonte
0

Meu problema não estava relacionado com processData. Foi porque enviei uma função que não pode ser chamada posteriormente applyporque não tinha argumentos suficientes. Especificamente, eu não deveria ter usado alertcomo errorretorno de chamada.

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

Veja esta resposta para obter mais informações sobre por que isso pode ser um problema: Por que certas chamadas de função são chamadas de "invocações ilegais" em JavaScript?

Descobri isso adicionando um console.log(list[ firingIndex ])ao jQuery para rastrear o que ele estava disparando.

Esta foi a solução:

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
});
ubershmekel
fonte
0

No meu caso (usando webpack 4) em uma função anônima, que eu estava usando como retorno de chamada.

Tive que usar em window.$.ajax()vez de $.ajax()ter:

import $ from 'jquery';
window.$ = window.jQuery = $;
Zanderwar
fonte
0

Além disso, esta é uma causa também: se você construiu uma coleção jQuery (via .map () ou algo semelhante), você não deve usar essa coleção nos dados .ajax (). Porque ainda é um objeto jQuery , não um array JavaScript simples . Você deve usar .get () no e para obter o array js simples e deve usá-lo na configuração de dados em .ajax ().

Burak TARHANLI
fonte