Intercept and modify JSON string before jQuery.getJSON() does its thing - javascript

I use jQuery's getJSON call to rerieve the content from a file called my.json.
Now sometimes the JSON file contains a certain character, that would invalidate the syntax. Unfortunately, it is not in my power to change that.
I thought it would be easy to use the success thing to intercept the JSON string and dix it, before $.getJSON() reads it and fails because the syntax is invalid. Obviously, it's not as easy, as I thought.
I would appreciate, if someone could help me out fixing below code.
$.ajaxSetup({
beforeSend: function(xhr){
if (xhr.overrideMimeType) {
xhr.overrideMimeType("application/json");
}},
cache: false
});
$.getJSON("my.json", function(data){
// Do something with the JSON
console.log("JSON object: " + data);
}).success(function(data, textStatus, jqXHR) {
// Intercept JSON string and modify it.
var fixed_json = fix_json(jqXHR.responseText);
jqXHR.responseText = fixed_json; // Obviously not as simple as I thought.
});

You can use the success callback of $.ajax() to do the required check on the returned data. It would require you to set the dataType to text though, so that jQuery doesn't try and automatically parse it for you. Try this:
$.ajax({
url: "my.json",
dataType: 'text',
success: function(data) {
var obj;
try {
obj = JSON.parse(data);
}
catch(e) {
obj = fix_json(data);
}
// work with the object here...
})
});
Example fiddle
Depending on the work that fix_json does, and assuming that it always returns an object, you could call that directly and remove the try/catch.

Related

Passing a string array to mvc controllers using ajax

I need to pass list of strings from multiple select to the controller. Though the requirement looked very simple to me, I was breaking my head for the past hour in this. I have did a fair research on this, but unable to succeed.
Below is my Javascript code. Please ignore the comments. I was successfully able to fetch the list of items in the multiple select. While i do the ajax call, I get the error "Object reference not set an instance of an object.
function submitForm() {
var selected = $('#selectedTasks option').map(function(){
return this.value
}).get()
var postData = { selectedTasks : selected } //corrected as suggested
//selectedTasks = JSON.stringify({ 'selectedTasks': selected });
alert(postData);
$.ajax({
type: "POST",
//contentType: 'application/json; charset=utf-8',
url: '#Url.Action("AssignTasks", "MonthEndApp")',
dataType: 'json',
data: postData,
traditional: true,
success: function (data) {
alert("Success");
},
error: function (xhr) {
alert(xhr.responseText);
}
});
}
MonthEndAppController.cs
[HttpPost]
public void AssignTasks(List<String> selectedTasks)
{
//do something
}
Can someone guide me where exactly I have gone wrong? Can someone suggest me what is wrong?
EDIT : As suggested by Mr. Rory I have made the java script changes. Now the Java script part works absolutely fine. But the Controller is not getting called when the ajax request is made. Can someone help me out if something wrong in the call made to controller ?
Have you tried with string[] instead of List<String> ?
The parameter your AssignTasks action is expecting is called selectedTasks, not values:
var postData = { selectedTasks: selected };
Also note that when debugging anything in JS you should always use console.log() over alert(), as the latter coerces all types to a string, which means you're not seeing a true representation of the actual value.

get json data with jquery

Hey guys I would like to know how can I get json data with ajax call.
I tried this but seems won't work :P
First I created a JavaScript file to put inside my json data elements :
var food = [
{'name':'bread', 'price':'7,25'},
{'name':'fish', 'price':'9,00'}
];
I saved it as food.js.
Then I tried to make an ajax call from an another file, this is my code :
$(document).ready(function(){
$.ajax({
async: false,
dataType: "json",
type:'GET',
url:"food.js",
success: function(data) {
var result = data.food.name;
alert(result);
});
}});
});
Any ideas?
Thanks in advance ;)
Firstly, you have a syntax error in your example - there's too many closing braces on the $.ajax call, although I guess that's just a typo.
In your JSON, food is an array, so you need to use an indexer to get the properties of the objects within it:
success: function(data) {
var result = data.food[0].name; // = "bread"
alert(result);
});
try this
$(document).ready(function() {
$.ajax({
async: false,
dataType: "json",
type:'GET',
url:"food.js",
success: function(data) {
var result = data.food[0].name;
alert(result);
}
});
});
You need to loop through the returned data since it's an array:
$.each(data,function(i,val) {
alert(data[i].name);
});
I love how people are completely ignoring the fact that your "food.js" is not a JSON string, it's JavaScript code. This might work on old-school eval-based "JSON", but with jQuery AJAX your target file should be plain JSON. Remove the var food = from the start, and the ; from the end.
Then you can access data.food[0].name;
In this case, you are trying to get an another javascript file via ajax. For do this, you can "include" your script ( of food.js ) in your page, using Ajax GetScript ( see here ).
Your code is mucth better when you request directly json files.
You probably want to use the getJSON function in jquery : http://api.jquery.com/jquery.getjson/
$.getJSON( "food.json", function( data ) {
//here your callback
}
It will set the datatype to json and the method to GET by default.
You should also use the .json extension and not the js extension for you jsons. And format it like a proper json :
{
"food": [
{
"name": "bread",
"price": 7.25
},
{
"name": "fish",
"price": 9.00
}
],
}
You can use this website to help you format jsons : http://www.jsoneditoronline.org/
The way you are trying to call your element won't work. The data you obtain is an array. In the callback, you can try this :
console.log(data)
console.log(data.food)
console.log(data.food[0])
console.log(data.food[0].name)
console.log(data.food[0].price)
Finally, note that you formatted your numbers with a coma, this is not the way you format numbers in javascript. Use a dot, that way you'll be able to manipulate it as a number.

JS Post to Php Issue

I am stuck on this one. I think this should be simple but I am have no success. I am just trying to post a variable in a href tag over to a php function on a separate file. I am trying to test my JS with an alert box on success. I am getting no alert box, 'Success alert box test!'.
Any idea what I am doing wrong? I am guessing it is the problem is with my success function.
Thanks again! Much appreciated.
HTML:
Click here
JS:
$(document).ready(function() {
$( ".target" ).click(function(e) {
e.preventDefault();
var review_id = this.data('review');
$.ajax({
url : "vote_add.php",
type : "POST",
dataType: "json",
data : {
reviewId : review_id
},
success : function(data) {
if (data == 'success') {
alert('Success alert box test!');
} else {
alert(data);
}
}
});
});
});
Vote_add.php:
<?php
echo "success";
?>
$(document).ready(function() {
$( ".target" ).click(function(e) {
e.preventDefault();
var review_id = $(this).data('review');
$.ajax({
url : "/echo/json/",
type : "POST",
dataType: "json",
data : {
reviewId : review_id
},
success : function(data, status) {
if (status == 'success') {
alert('Success alert box test!');
} else {
alert(data);
}
}
});
});
});
You have error on line 5th this should be $(this) - the jQuery object and also you should use 2nd parameter for success which is status.
For easier debug just use FireBug or DevTools.
A couple things to improve your code and to my experience, what I believe you should change:
$(this).data('review') should work.
The .data() method allows us to attach data of any type to DOM elements in a way that is safe from circular references and therefore from memory leaks.
As of jQuery 1.6, the .prop() method provides a way to explicitly retrieve property values, while .attr() retrieves attributes.
Your callback functions on the $.ajax() options you provide should be like .done(), .fail(), .always() and .then()
The jqXHR objects returned by $.ajax() as of jQuery 1.5 implement the Promise interface, giving them all the properties, methods, and behavior of a Promise.
Deprecation Notice: The jqXHR.success(), jqXHR.error(), and jqXHR.complete() callbacks are deprecated as of jQuery 1.8.
Depending on the way your web service was setup, you should be able to set a breakpoint in your server code (I assume you have access to it or built it yourself?). If not possible, check the data object returned by .fail() with Firebug or any other developer toolbar and look for xhr.statusText or xhr[0].statusText (again, depending on how your web service returns it.)
Success: Type: Function( PlainObject data, String textStatus, jqXHR jqXHR )
A function to be called if the request succeeds. The function gets passed three arguments: The data returned from the server, formatted according to the dataType parameter; a string describing the status; and the jqXHR (in jQuery 1.4.x, XMLHttpRequest) object.
jqXHR.done(function( data, textStatus, jqXHR ) {});
An alternative construct to the success callback option, the .done() method replaces the deprecated jqXHR.success() method.
If you are using "POST" to the web service you might want to send it as a JSON string.
JSON.stringify() can assist with that. Some browser support is lacking but you can fix this with a polyfill
Last but not least, if you are sending json you want to expect json back. <? echo "success" ?> isn't going to cut it I'm afraid. Check out this post to see what I mean.
The json type parses the fetched data file as a JavaScript object and returns the constructed object as the result data. To do so, it uses jQuery.parseJSON() when the browser supports it; otherwise it uses a Function constructor. Malformed JSON data will throw a parse error (see json.org for more information). JSON data is convenient for communicating structured data in a way that is concise and easy for JavaScript to parse. If the fetched data file exists on a remote server, specify the jsonp type instead.
.
$(function () {
var ajaxOptions = {
url: "vote_add.php",
type: "POST",
dataType: "json"
};
$(".target").click(function (e) {
var options,
optionsData = {
reviewId: $(this).data('review')
};
e.preventDefault();
//options = $.extend({}, ajaxOptions, { data: optionsData });
options = $.extend({}, ajaxOptions, { data: JSON.stringify(optionsData) });
$.ajax(options).done(function (data) {
// success so use your data object
// are you looking for a property?
var myProperty = 'myProperty';
if (data.hasOwnProperty(myProperty)){
var myValue = data[myProperty];
}
}).fail(function (xhr) {
// do something on error
console.warn("myscript.js > " + xhr.statusText + ' ' + xhr.status);
}).always(function() {
// do something no matter what happens
});
});
});

JQuery parse JSON

I'm fairly new to JQuery. The code below works and I can see the correct JSON response in Firebug. But I couldn't find a way how to get and parse it in the code. Alert window only shows
"[object Object]" but not any json text.
<script>
$.ajaxSetup({ cache: false });
var _token;
function make_token_auth(user, token) {
var tok = user + ':' + token;
return "Token " + tok;
}
$.ajax
({
type: "GET",
url: "url",
dataType: 'json',
beforeSend: function (xhr){
xhr.setRequestHeader('Auth', make_token_auth('userid', 'token'));
},
success: function (data){
alert(data);
}
});
</script>
The fact you precised
dataType: 'json',
tells jQuery to parse the received answer and give it as a javascript object to your success callback.
So what you have here is fine and what is alerted is correct (this is an object, so
alert simply prints the result of data.toString()).
Use console.log to see what it is exactly :
success: function (data){
console.log(data);
}
and open the developer tools in Chrome or the console in Firebug to browse the properties of the object.
don't use alert() for debugging -- it's often unhelpful (as in this case), and also has serious issues when used with asyncronous code (ie anything Ajax) because it interrupts the program flow.
You would be much better off using the browser's console.log() or console.dir() functions, and seeing the object displayed in the console. It is much more functional, and doesn't interrupt the flow of the program.
So instead of alert(myjsonvar) use console.log(myjsonvar).
You can get the json string by using JSON.stringify
var jsonstr = JSON.stringify(data);
alert(jsonstr);
The alert function expects you to pass in a string or number.
Try doing something like this:
for(x in data) {
alert(x + ': ' + data[x]);
}
Update in response to comments: You can use alert in development or production to see string and number values in the object returned by the server-side code.
However, carefully rereading your question, it looks like what you really want to see is the actual JSON text. Looking at #dystroy's answer above, I think that if you remove the dataType: 'json' from your $.ajax invokation, jQuery will treat the response as plain text instead of automatically converting it to an Object. In this case, you can see the text by passing it to the alert function.
Try using
data = JSON.parse(data)
Then do whatever you want with the data.
Source: JSON.parse() (MDN)

$.ajax JSON not passing values on complete

I'm having an annoying issue, on complete i get undefined when trying to make simple url validation. success working fine.
i get a valid json response:
{"error":"some error"}
and this is my jQuery
$("#myform").submit(function(){
dataString = $("#myform").serialize();
$.ajax({
type: "GET",
url: "myform.php",
data: $.URLDecode(dataString), //fixing url problem
dataType: "json",
beforeSend: function(){
$('#search').append('<img src="images/ajax-loader.gif" />'); //loader
$('.error').remove(); //removes every submit
},
success: function(data){
$('<span class="error">' + data.error + '</span>').appendTo($('#search'));
},
complete: function(data){
$('#search img').fadeOut(); //removes loader
alert(data.error);
}
});
return false; //force ajax submit
});
Any hint please?
If you look at the docs:
complete(XMLHttpRequest, textStatus)
A function to be called when the
request finishes (after success and
error callbacks are executed). The
function gets passed two arguments:
The XMLHttpRequest object and a string
describing the status of the request.
This is an Ajax Event.
Data is not a return value from your method.
If you're using firebug, use console.log(XMLHttpRequest) and you'll see what it includes.
You can also do this (quick - using eval here - not recommended.)
var err = eval("(" + XMLHttpRequest.responseText + ")");
alert(err.Message);
As per the docs, the complete event doesn't hold your json response.
Why do you need to define the complete handler and the success handler? Just define success.
maybe $.URLDecode() returns not JSON key/value structure
I think you want URLEncode not URLDecode? Either way I'd recommend fiddler for debugging issues like this - it'll show you exactly what's being sent to/from the server.

Categories

Resources