3

I have an Ajax call that returns a json hash including errors if anything goes wrong. Here's an example:

{"success":false,"errors":{"image":["file must be at least 1024x768px in size."]},"content_type":"text/json"}

Based on this question I was able to figure out that I could print part of this hash like so:

JSON.stringify( responseJSON.errors )

However this still prints as a code hash, like: {"image":["file must be at least 1024x768px in size."]}

I would really like to convert this to simply:

Image file must be at least 1024x768px in size.

Short of using .replace after stringify, is there a straightforward way to do this? Note that the errors hash could contain more errors, for instance:

{"image":["file must be at least 1024x768px in size."],"file":["type is invalid, must be jpg, png, or gif"]}

Update: I don't know why, but none of the functions shown below would return a string when passed the responseJSON object. However, appending directly to the DOM using jQuery did work. Here's what I ended up doing:

// In the middle of an ajax callback
$('.qq-upload-failed-text:last').append(': <span class="explanation"></span>');
formatErrors( responseJSON );

// As a stand-alone function so it can be reused
function formatErrors( response ) {
  $.each( response.errors, function(key, value) {
    $('span.explanation:last').append( key + " " + value );
  });
}

Why that would insert the text correctly into the dom but using Dampsquid's function or any of the others would only return an empty string is beyond me.

Community
  • 1
  • 1
Andrew
  • 42,517
  • 51
  • 181
  • 281
  • It sounds like you want to loop over the object and assemble a string yourself. – SLaks Mar 07 '12 at 22:08
  • Well, this is in the middle of a bunch of other code, so basically what I want to do is create a simple function that I can pass the error object to and return a string. – Andrew Mar 07 '12 at 22:28

8 Answers8

3

Iterate over the errors and append them to an element.

$("#errors").empty();
$.each(responseJSON.errors, function(key, value) {
    $("#errors").append("<div>" + key + " " + value + "</div>");
});
Kevin B
  • 94,570
  • 16
  • 163
  • 180
2

You can iterate over the errors like so:

for (var name in responseJSON.errors) {
    var message = responseJSON.errors[name];
}

Not sure how you want to display the error message(s) so I'll leave that up to you. But this should be enough to get the information you want out of your JSON object.

Kevin Pang
  • 41,172
  • 38
  • 121
  • 173
1

Based on your JSON: var myStr = "Image " + responseJSON.errors.image[0];

If you wanted to get all errors and their will be more than one:

var errors = '';
for(var i = 0; i<responseJSON.errors; i++) {
   errors += responseJSON.errors[i] + ','
}
Justin Thomas
  • 5,680
  • 3
  • 38
  • 63
1
var response = {"image":["file must be at least 1024x768px in size."],"file":["type is invalid, must be jpg, png, or gif"]};

var errors = "";
for (var prop in response) {
    errors += prop + ": " + response[prop] + "\n";
}
alert(errors);

Working example: http://jsfiddle.net/zFdmZ/3/

Sean
  • 15,561
  • 4
  • 37
  • 37
  • I'm starting with a json object `responseJSON`, which I call `.errors` on, as in `responseJSON.errors`, to get the errors object. For some reason when I do this as in your example, ie. `var response = responseJSON.errors`, it only returns an empty string. Any ideas? – Andrew Mar 07 '12 at 22:35
  • If you log or alert `JSON.stringify(responseJSON, null, 4)` you will get a good view of how the data is structured. You do the same on responseJSON.errors etc. – Sean Mar 07 '12 at 22:57
1

Heres a simple pure JS solution,

It also takes into account that each type of error has an Array of possible error texts.

JSFiddle

function FormatErrors( response )                                  
{
    var s = "";
    for( var name in response.errors )
    {
        s += "<p><span class='error'>" + name + ":</span> ";
        s += response.errors[name].join( "</p><p><span class='error'>"+name+ ":</span> " );
        s += "</p>";
    }
    return s;
}                                                                 

Edit:

Updated to add simple css formatting and return a string to allow insertion into another element. Also updated Fiddle.

Community
  • 1
  • 1
Dampsquid
  • 2,456
  • 15
  • 14
  • For what it's worth I'd like to make a function that returns a string so I can easily incorporate it into various callbacks etc. where I'm getting the response object and want to insert the error messages into the DOM. – Andrew Mar 07 '12 at 22:38
  • Your idea looks like it would work but for some reason it doesn't. If I put `console.log(s)` before the return it shows `[an empty string]`. For some reason when called in a function the keys and values are not willing to convert to a string... – Andrew Mar 08 '12 at 02:24
  • I see that it works fine in the fiddle, the problem is something about the nature of the response object that I don't understand. Unfortunately my JS knowledge is very limited so I have no idea what the difference would be. Thanks for the answer and the help. – Andrew Mar 08 '12 at 19:38
0

The JSON response is actually an object, so you can just read its property. Just like you can read responseJSON.errors, you can also read responseJSON.errors.image[0] to read the first item of the image array in the errors sub-object of the JSON response.

alert(responseJSON.errors.image[0]);
GolezTrol
  • 114,394
  • 18
  • 182
  • 210
0

You better loop over your object instead of trying to stringify it and apply string methods afterwards.

var json = {"image":["file must be at least 1024x768px in size."],"file":["type is invalid, must be jpg, png, or gif"]},
    output = [];

for( var key in json ) {
  output,push( key + ' ' + json[key] );
}

output = ouput.join( '<br />' );
Sirko
  • 72,589
  • 19
  • 149
  • 183
0

For this type of task, I tend to use the amazing underscore.js library. Then you can do something like the following:

function parseErrors(responseJSON) {
  var errs = JSON.stringify(responseJSON.errors),
    errStr = _(errs).reduce(function (memo, str, key) { 
      return memo + "\n" + key + " " + str;
    }, '');
    return errStr.replace(/^\n/, '');
}

This will return something like:

image file must be at least 1024x768px in size.
file type is invalid, must be jpg, png, or gif

Depending on where you're implementing this, you could do something similar with the native Array reduce() function (see MDN documentation).

Also, you could replace the newline "\n" with HTML break elements <br /> if necessary.

Horatio Alderaan
  • 3,264
  • 2
  • 24
  • 30