¿Alguna idea de por qué mi función jQuery .ajax() no ejecutará la parte de 'éxito'?

Tengo el siguiente código:

$.ajax({
    async: false,
    url: 'chart_data.php',
    data: {'option':'high', 'id':id},
    dataType: 'json',
    success: function(response){
        alert('in');
        var data = google.visualization.arrayToDataTable(response);
        var options= { curveType:'none', width: 300, height: 200, hAxis: {title:'Years'}, vAxis: {title:'Value'}, title: 'High Time - Low Value' };
        var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
        chart.draw(data, options);  
    }
});

en una página web. Me gustaría que se muestre el gráfico, basado en un menú desplegable. El resto de la función funciona bien. Revisé Firebug y la respuesta JSON aparece con un mensaje de estado 200 OK. De hecho, puedo ver todo el JSON muy bien en Firebug.

Queda la pregunta, ¿por qué el alert('in'); nunca se activa, y ¿por qué Google no carga su gráfico en el div de gráfico asociado?

Edit:

Recibo el siguiente error al agregar una devolución de llamada de error: parseerror SyntaxError: JSON.parse: carácter inesperado.

Esta es la respuesta JSON del servidor:

[['Year', 'Low', 'High'],['1984', 318000, 395000],['1984', 418000, 495000],
['1984', 380000, 450000],['1984', 410000, 460000],['1984', 410000, 460000],
['1985', 435000, 485000],['1985', 435000, 485000],['1985', 435000, 485000],
['1985', 435000, 485000],['1985', 435000, 485000],['1985', 435000, 485000],
['1985', 435000, 485000],['1985', 435000, 485000],['1985', 318000, 395000],
['1985', 418000, 495000],['1985', 380000, 450000],['1985', 420000, 470000],
['1985', 420000, 470000]]

Me parece correcto, aunque no estoy 100% seguro de la estructura JSON.

Edit:

He hecho algunos cambios, y parece que estoy avanzando un poco más. Primero, eliminé el header('Content-type: application/json'); línea de mi script php. Luego cambié el dataType: 'json' a dataType: 'html'.

Ahora carga la devolución de llamada correcta en la llamada $.ajax(). No le gusta la respuesta de texto cuando trato de enviar eso al método arrayToDataTable() de Google.

Si puedo obtener la cadena devuelta (que se parece a la respuesta JSON anterior que en realidad no es una respuesta JSON) para ser analizada en una matriz de JavaScript, entonces estaría bien. Ojala.

Edit:

Terminé usando una declaración de evaluación en mi devolución de llamada exitosa para convertir la respuesta http en una matriz eval('var res = ' + response); Probablemente esta no sea la mejor manera de hacerlo. Si alguien tiene una forma mejor (y más segura) de hacerlo, sería genial.

Edit:

Realmente no me gustaba usar la declaración eval, así que busqué otras formas de cambiar la cadena de retorno en una matriz. Realmente no me importaba ninguno de ellos hasta que encontré esta pequeña joya:

response = JSON.parse(response);

Esto funciona sin problemas.

Gracias por la ayuda de todos.

preguntado el 12 de junio de 12 a las 20:06

¿Tienes algún error en la consola? -

No especificó un tipo, es decir, POST o GET. -

@ clockwork189, no tiene que especificar, el valor predeterminado es GET, por lo que, a menos que desee POST, debe definirlo. -

Ajá, mis disculpas por la falta de comunicación, pero sí, @Gabe, lo que quise decir es que podría ser una solicitud posterior y se ha predeterminado en GET -

Podrías intentar agregar un error devolución de llamada para ver e imprimir la información final que puede obtener. -

2 Respuestas

OK, nadie ha respondido todavía, así que lo intentaré aquí. Parece que ha actualizado con un mensaje de error y el valor de retorno que está obteniendo de la llamada ajax.

El problema es que lo que está recibiendo no es un objeto JSON, sino una matriz de JavaScript. Los objetos JSON estarán encerrados entre corchetes { y } mientras que las matrices estarán encerradas entre corchetes [ y ].

Debe modificar el script que está llamando a través de ajax para que devuelva un objeto JSON adecuado (usando json_encode en php es bastante útil).

Usted querrá que su respuesta se parezca más a esto:

{"data":[["Year", "Low", "High"],["1984", 318000, 395000],["1984", 418000, 495000],
["1984", 380000, 450000],["1984", 410000, 460000],["1984", 410000, 460000],
["1985", 435000, 485000],["1985", 435000, 485000],["1985", 435000, 485000],
["1985", 435000, 485000],["1985", 435000, 485000],["1985", 435000, 485000],
["1985", 435000, 485000],["1985", 435000, 485000],["1985", 318000, 395000],
["1985", 418000, 495000],["1985", 380000, 450000],["1985", 420000, 470000],
["1985", 420000, 470000]]}

Según google, están buscando algo como esto:

{
   cols: [{id: 'task', label: 'Task', type: 'string'},
          {id: 'hours', label: 'Hours per Day', type: 'number'}
   ],
   rows: [{c:[{v: 'Work'}, {v: 11}]},
          {c:[{v: 'Eat'}, {v: 2}]},
          {c:[{v: 'Commute'}, {v: 2}]},
          {c:[{v: 'Watch TV'}, {v:2}]},
          {c:[{v: 'Sleep'}, {v:7, f:'7.000'}]}
   ]
 }

Entonces, ¿quizás realmente necesite volver a trabajar sus datos para seguir esta estructura primero? Algo como esto:

{
  "cols": [{"id":"year", "label":"Year", "type":"string"},
         {"id":"low",  "label":"Low",  "type":"string"},
         {"id":"high", "label":"High", "type":"string"}],
  "rows": [{"c":[{"v":"1984"}, {"v":"318000"}, {"v":"395000"}]},
         {"c":[{"v":"1984"}, {"v":"418000"}, {"v":"495000"}]},
         {"c":[{"v":"1984"}, {"v":"380000"}, {"v":"450000"}]},
         {"c":[{"v":"1985"}, {"v":"420000"}, {"v":"470000"}]}]
}

Si JSON parece un poco confuso, puede leer más sobre esto aquí: http://www.json.org/

EDITAR

Teniendo en cuenta que pasé por alto la llamada a la función .arrayToDataTable(), creo que debería haber citado este ejemplo de la documentación de Google (el enlace ya se menciona arriba):

// Version 1: arrayToDataTable method
var data2 = google.visualization.arrayToDataTable([
  ['Country', 'Population', 'Area'],
  ['CN', 1324, 9640821],
  ['IN', 1133, 3287263],
  ['US', 304, 9629091],
  ['ID', 232, 1904569],
  ['BR', 187, 8514877]
]);

Dado que su matriz está llegando así:

[['Year', 'Low', 'High'],
 ['1984', 318000, 395000],
 ['1984', 418000, 495000],
 ['1984', 380000, 450000],
 ['1984', 410000, 460000],
 ['1984', 410000, 460000],
 ['1985', 435000, 485000],
 ['1985', 435000, 485000],
 ['1985', 435000, 485000],
 ['1985', 435000, 485000],
 ['1985', 435000, 485000],
 ['1985', 435000, 485000],
 ['1985', 435000, 485000],
 ['1985', 435000, 485000],
 ['1985', 318000, 395000],
 ['1985', 418000, 495000],
 ['1985', 380000, 450000],
 ['1985', 420000, 470000],
 ['1985', 420000, 470000]]

Lo que parece tener el formato correcto, creo que debería intentar cambiar su "tipo de datos" en su llamada ajax a "texto" en lugar de "json", ya que realmente está devolviendo una matriz y no un objeto JSON. Esto debería solucionar tu problema.

Respondido el 21 de junio de 12 a las 17:06

Gracias, lo intentaré más tarde hoy. Ha sido un poco molesto tratar de hacer que esto funcione correctamente. - Jim P.

Así que intenté poner {} alrededor del bloque de datos en lugar de []. Esto me da un parserror: JSON.parse: nombre de propiedad esperado o '}' en lugar del carácter inesperado. En cuanto al formato de google, estoy usando el método googles .arrayToDataTable() para generar los datos a partir de una matriz de valores. - Jim P.

OK, agregué la respuesta. Eche un vistazo a la última mitad de mi respuesta, creo que simplemente cambiar su tipo de datos en su llamada ajax a "texto" debería resolver su problema. - mason81

Todavía tenía problemas con el método arrayToDataTable(), pero después de instalarlo response = JSON.parse(response);, no hubo ningún problema para que funcionara. Sin embargo, me pregunto por qué el método parseJSON() de jQuery estaba teniendo tantas dificultades con la cadena. - Jim P.

que version de jquery estas usando? aquí hay una publicación / respuesta SO sobre la diferencia entre las dos funciones: stackoverflow.com/questions/10362277/… - mason81

Hay un error en el formato de su JSON, la cadena debe estar entre comillas dobles (") y no entre comillas simples (')

Si desea comprobar que su JSOn es válido, puede utilizar así

Respondido el 20 de junio de 12 a las 21:06

Gracias por eso. Puedo probarlo más tarde ya que realmente no quiero tener una declaración de evaluación simplemente en el código de producción. - Jim P.

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.