JQuery: 'Uncaught TypeError: Illegal invocation' en la solicitud ajax - varios elementos

112

Tengo dos elementos seleccionados, A y B: cuando la opción seleccionada de A cambia, las opciones de B deben actualizarse en consecuencia. Cada elemento en A implica muchos elementos en B, es una relación de uno a muchos (A contiene naciones, B debe contener ciudades ubicadas en la nación dada).

La función do_ajaxdebe ejecutar la solicitud asincrónica:

function do_ajax(elem, mydata, filename)
{
    $.ajax({
        url: filename,
        context: elem,
        data: mydata,
        datatype: "html",
        success: function (data, textStatus, xhr) {
            elem.innerHTML = data;
        }
    });
}

Para actualizar las opciones de B, agregué una llamada de función en el onChangeevento de A. Aquí está la función que se ejecuta cuando se activa el evento onChange (of A):

function my_onchange(e) // "e" is element "A"
{
    var sel_B = ... ; // get select element "B"

    // I skipped some code here
    // ...

    var data = {
        'mode': 'filter_city',
        'id_A': e[e.selectedIndex]
    };
    do_ajax(city_sel, data, 'ajax_handler.php');
}

}

He leído en documentos de JQuery que datapueden ser una matriz (pares clave-valor). Me sale el error si pongo:

var data = {
        'mode': 'filter_city',
        'id_A': e[e.selectedIndex]
};

En cambio, no obtengo ese error si mis datos son una cadena:

var data = 'mode=filter_city&id_A=' + e[e.selectedIndex];

Pero necesito la "versión de matriz" de la variable, en mi código php del lado del servidor.

los Uncaught TypeError: Illegal invocation encuentra en el archivo "jquery-1.7.2.min.js", que está totalmente comprimido, por lo que no pude averiguar qué parte del código generó el error.

¿Hay alguna configuración que pueda cambiar en mi código para que acepte datos como una matriz asociativa?

Nadir Sampaoli
fuente

Respuestas:

151

Gracias a la charla con Sarfraz pudimos encontrar la solución.

El problema era que estaba pasando un elemento HTML en lugar de su valor, que en realidad es lo que quería hacer (de hecho, en mi código php necesito ese valor como clave externa para consultar mi citiestabla y filtrar las entradas correctas).

Entonces, en lugar de:

var data = {
        'mode': 'filter_city',
        'id_A': e[e.selectedIndex]
};

debería ser:

var data = {
        'mode': 'filter_city',
        'id_A': e[e.selectedIndex].value
};

Nota: verifique la respuesta de Jason Kulatunga , cita el documento de JQuery para explicar por qué pasar un elemento HTML estaba causando problemas.

Nadir Sampaoli
fuente
exactamente lo que estaba haciendo. Olvidé usar .val ()
Usman Shaukat
Estaba pasando la opción de un elemento html seleccionado en una variable. No me di cuenta de que no era texto plano sino html.
Sterling Diaz
46

De los documentos de jQuery para processData:

processData Boolean
Predeterminado: verdadero
De forma predeterminada, los datos pasados ​​a la opción de datos como un objeto (técnicamente, cualquier cosa que no sea una cadena) se procesarán y transformarán en una cadena de consulta, que se ajusta al tipo de contenido predeterminado "application / x-www -form-urlencoded ". Si desea enviar un DOMDocument u otros datos no procesados, establezca esta opción en falso.

Fuente: http://api.jquery.com/jquery.ajax

Parece que tendrá que usarlo processDatapara enviar sus datos al servidor o modificar su script php para admitir parámetros codificados de cadena de consulta.

Jason Kulatunga
fuente
1
Esto es verdad. Si pudiera haberlo visto antes, me habría señalado el error real en mi código. Gracias, agregaré una nota en mi respuesta.
Nadir Sampaoli
25

Recibí este error al publicar un objeto FormData porque no estaba configurando la llamada ajax correctamente. La configuración a continuación solucionó mi problema.

var myformData = new FormData();        
myformData.append('leadid', $("#leadid").val());
myformData.append('date', $(this).val());
myformData.append('time', $(e.target).prev().val());

$.ajax({
    method: 'post',
    processData: false,
    contentType: false,
    cache: false,
    data: myformData,
    enctype: 'multipart/form-data',
    url: 'include/ajax.php',
    success: function (response) {
        $("#subform").html(response).delay(4000).hide(1); 
    }
});
Mike Volmar
fuente
gracias hombre. me salvaste el día y mi problema se resuelve agregando "processData: false, contentType: false, cache: false" en mi cuerpo ajax. Muchas gracias.
CumaTekin
11

He leído en documentos de JQuery que los datos pueden ser una matriz (pares clave-valor). Me sale el error si pongo:

Este es un objeto, no una matriz:

var data = {
        'mode': 'filter_city',
        'id_A': e[e.selectedIndex]
};

Probablemente quieras:

var data = [{
        'mode': 'filter_city',
        'id_A': e[e.selectedIndex]
}];
Sarfraz
fuente
1
ya no arroja ese error, pero parece que estos datos no se pasan a mi $_GETmatriz del lado del servidor ( var_export($_GET)salidas array ( 'undefined' => 'undefined', ))
Nadir Sampaoli
@nadirs: intente definir el tipo de método en su $.ajaxcontrolador:type:'get',
Sarfraz
@Sarfraz el resultado es el mismo. Las dataclaves del lado del servidor deben encontrarse en la matriz GET, ¿verdad? ¿O tal vez se envían a través de otro método de solicitud de todos modos?
Nadir Sampaoli
@nadirs: Algo como esto funciona data: {foo:'myfoo', bar:'mybar'}, creo que podría haber algún otro problema.
Sarfraz
@Sarfraz Soy un idiota, estaba enviando un objeto HTML e[e.selectedIndex]mientras debería haber pasado su valor e[e.selectedIndex].value. Después de corregir este defecto, la notación de objetos funciona bien.
Nadir Sampaoli
7

Tuve el mismo problema recientemente, resuelto agregando traditional: true,

deco
fuente
Sin embargo
barnacle.m
0
function do_ajax(elem, mydata, filename)
{
    $.ajax({
        url: filename,
        context: elem,
        data: mydata,
        **contentType: false,
        processData: false**
        datatype: "html",
        success: function (data, textStatus, xhr) {
            elem.innerHTML = data;
        }
    });
}
Derly Pacheco
fuente
4
Una buena respuesta es más que un simple fragmento de código. Debe explicar por qué esto responde a la pregunta inicial y proporcionar enlaces a la documentación relevante, si está disponible.
JSTL
Sin los dos campos contentTypey processData, el error seguirá apareciendo. Agregué los dos campos y funcionó para mí. Creo que op estaba tratando de indicar los dos campos importantes.
Ekundayo Blessing Funminiyi
-1
$.ajax({
                    url:"",
                    type: "POST",
                    data: new FormData($('#uploadDatabaseForm')[0]),
                    contentType:false,
                    cache: false,
                    processData:false,
                    success:function (msg) {}
                  });
Nitin Sharma
fuente
7
Las respuestas son más útiles si incluye una explicación.
Jon B
-2

Prueba esto:

            $.ajax({
                    url:"",
                    type: "POST",
                    data: new FormData($('#uploadDatabaseForm')[0]),
                    contentType:false,
                    cache: false,
                    processData:false,
                    success:function (msg) {}
                  });
Ali Asad
fuente