Given a JSON respond to a form I need to parse through the JSON elements to find error messages with their associated element the error is tied to.
The data is returned in JSON format with the error messages as the last variable pair looking like this:
"invalid":[{"field1":"Field 1 is required"}]
This ends up having an object/array for each error showing the item's name(key) along with the associated error for that field. Given that my error handling form is unaware what the key names will be how do I go about getting both the key and the value out of this object/array?
I'm using dojo on this project and I'm not familiar with it at all so I've been attempting to use dojo functions when possible if something exists that can handle this. Currently there is where I am :
var retObj = dojo.fromJson(ioargs.xhr.responseText);
dojo.forEach(retObj.invalid, function(entry,i){
console.debug(entry);
});
The console output is:
Object { field1="Field 1 is required"}
My goal is to pull out the value "field1" so I know which input field this error is assigned to, then to assign the value of field1 to that error field.
Thanks!
Dunno a single thing about Dojo, but you're looking for a pretty basic for in loop.
var retObj = dojo.fromJson(ioargs.xhr.responseText),
invalids = retObj.invalid[0],
res = {}; //here will be your final key=>value
for (var key in invalids) {
res[key] = invalids[key];
}
http://jsfiddle.net/DgXkq/
You might also be interested in https://stackoverflow.com/search?q=%5Bjavascript%5Dparsing+json
There is no way to find the key of an object if you don't have access to the parent object. I believe the best solution in this case would be to massage the JSON to pass more meaningful information to the validator, that is, an object with two properties, fieldName and errorMessage.
// Returns the name of an object's first key
function getKeyName(obj) {
for (var prop in obj) {
return prop;
}
}
// This is the response from the server
var response = { "invalid":[{"field1":"Field 1 is required"}] };
// This is going to be the massaged array that
// contains more meaningful information.
var invalids = [];
for (var i=0; i < response.invalid.length; i++) {
var obj = response.invalid[i];
var key = getKeyName(obj);
invalids.push({fieldName: key, errorMessage: obj[key]})
}
Now invalids contains an array of more meaningful error message objects like
invalids = [{fieldName: 'field1', errorMessage: 'Field 1 is required'}]
Just pass that object to your validation routine. If possible, I would change the server code to return error messages in the format I suggested so you don't have to do extra work.
Related
I'm having a Laravel backend return some errors via Validator. These errors are passed through a HTTP response made by angular, and returned in JSON format.
The object is structured as seen below:
That name object has a value, which is the actual message that I'm after.
Currently, using loops etc., I can only get the name of the array (name) as a string...
I sometimes get multiple arrays within this error object, and I won't always know their names, so how may I retrieve that 0-index value in each of them, in a loop?
Thanks for any help.
Edit #1
Looping through it like this:
for(var err in res.data.errors){
console.log(Object.err[0][0]);
}
Gives me a Cannot get [0] index of undefined
How about this:
let errors = Object.values(response.data.errors);
// errors is now an array of arrays containing the validation errors
errors.forEach( (errorArray) => {
console.log(errorArray[0]);
} );
Another approach would be using Object.keys() instead of values. This is similar to what you already tried, where you get the name of the error property as a string, and then use it to access each error array:
let keys = Object.keys(response.data.errors);
keys.forEach( (errorKey) => {
console.log('error type', errorKey);
let errorArray = response.data.errors[errorKey];
console.log(errorArray[0]);
} );
Using C# regex i have sent modelState object to the java script and add it in the var type temp. Now this object have multiple arrays with in.
One way is to specify the key and get all error msgs from this object like
{{modelState["employee.FirstName"][0]}}
{{modelState["employee.Email"][0]}}
{{modelState[".............."][0]}}
There are almost 8 to 10 key pairs that maybe returns and will take time to write all key value. How do i iterate from this arrays inside object and get all the errors with out specifying the key value.
You could:
var allErrors = [];
$.each( modelState, function( name, errors ){
allErrors = allErrors.concat(errors);
} );
{"profit_center" :
{"branches":
[
{"branch": {"work_order":"1","cutover":"1","site_survey":"1","branch_number":"3310","quote":"1","configuration":"1","purchase_order":"1","hardware_swap":"1"}},
{"branch":{"work_order":"1","cutover":"1","site_survey":"1","branch_number":"3311","quote":"1","configuration":"1","purchase_order":"1","hardware_swap":"1"}},
{"branch":{"work_order":"1","cutover":"0","site_survey":"1","branch_number":"3312","quote":"1","configuration":"1","purchase_order":"1","hardware_swap":"1"}},
{"branch":{"work_order":"1","cutover":"1","site_survey":"1","branch_number":"3313","quote":"1","configuration":"1","purchase_order":"1","hardware_swap":"1"}},
{"branch":{"work_order":"1","cutover":"0","site_survey":"1","branch_number":"3314","quote":"1","configuration":"1","purchase_order":"1","hardware_swap":"1"}},
{"branch":{"work_order":"1","cutover":"1","site_survey":"1","branch_number":"3315","quote":"1","configuration":"1","purchase_order":"1","hardware_swap":"1"}}
],
"profit_center_name":"Alabama"}}
I tried accessing it in ajax through this,
data.profit_center //data here is the ajax variable e.g. function(data)
or through this data["profit_center"]
but no luck
How do I access this javascript object properly. ?
By the way that code above is from console.log(data)
EDIT:
Result from console.log(data.profit_center) and console.log(data["profit_center"]) is undefined
You can put your datain a variable like
var json = data
and you can access profit_center like
alert(json.profit_center);
alert(json.profit_center.profit_center_name); //Alabama
for(var i =0 ;i<json.profit_center.branches.length;i++){
alert(json.profit_center.branches[i]);
}
Okay I have found out why it is undefined, It is a json object so I need to parse it before i can access it like a javascript object.
var json = JSON.parse(data);
Then that's it.
First parse your data if you've not already done so.
You can access, for example, each branch_number like so:
var branches = data.profit_center.branches;
for (var i = 0, l = branches.length; i < l; i++) {
console.log(branches[i].branch.branch_number);
}
In summary, profit_center is an object and branches is an array of objects. Each element in the array contains a branch object that contains a number of keys. Loop over the branches array and for each element access the branch object inside using the key names to get the values.
The profit center name can be found by accessing the profit_center_name key on the profit_center object:
console.log(data.profit_center.profit_center_name); // Alabama
You could even use the new functional array methods to interrogate the data and pull out only those branches you need. Here I use filter to pull those objects where the purchase_order is equal to 2. Note that the numeric values in your JSON are strings, not integers.
var purchaseOrder2 = branches.filter(function (el) {
return el.branch.purchase_order === '2';
});
DEMO for the three examples
This is the array:
{"C8_235550":
{"listing":"aut,C8_235550_220144650654"},
"C8_231252":
{"listing":"aut,C8_231252_220144650654"}}
It was fetched with a GET request from a Firebase database using Google Apps Script.
var optList = {"method" : "get"};
var rsltList = UrlFetchApp.fetch("https://dbName.firebaseio.com/KeyName/.json", optList );
var varUrList = rsltList.getContentText();
Notice the .getContentText() method.
I'm assuming that the array is now just a string of characters? I don't know.
When I loop over the returned data, every single character is getting pushed, and the JavaScript code will not find key/value pairs.
This is the FOR LOOP:
dataObj = The Array Shown At Top of Post;
var val = dataObj;
var out = [];
var someObject = val[0];
for (var i in someObject) {
if (someObject.hasOwnProperty(i)) {
out.push(someObject[i]);
};
};
The output from the for loop looks like this:
{,",C,8,_,2,3,5,5,5,0,",:,{,",l,i,s,t,i,n,g,",:,",a,u,t,,,C,8,_,2,3,5,5,5,0,_,2,2,0,1,4,4,6,5,0,6,5,4,",},,,",C,8,_,2,3,1,2,5,2,",:,{,",l,i,s,t,i,n,g,",:,",a,u,t,,,C,8,_,2,3,1,2,5,2,_,2,2,0,1,4,4,6,5,0,6,5,4,",},}
I'm wondering if the array got converted to a string, and is no longer recognized as an array, but just a string of characters. But I don't know enough about this to know what is going on. How do I get the value out for the key named listing?
Is this now just a string rather than an array? Do I need to convert it back to something else? JSON? I've tried using different JavaScript array methods on the array, and nothing seems to return what it should if the data was an array.
here is a way to get the elements out of your json string
as stated in the other answers, you should make it an obect again and get its keys and values.
function demo(){
var string='{"C8_235550":{"listing":"aut,C8_235550_220144650654"},"C8_231252":{"listing":"aut,C8_231252_220144650654"}}';
var ob = JSON.parse(string);
for(var propertyName in ob) {
Logger.log('first level key = '+propertyName);
Logger.log('fisrt level values = '+JSON.stringify(ob[propertyName]));
for(var subPropertyName in ob[propertyName]){
Logger.log('second level values = '+ob[propertyName][subPropertyName]);
}
}
}
What you have is an object, not an array. What you need to do is, use the
Object.keys()
method and obtain a list of keys which is the field names in that object. Then you could use a simple for loop to iterate over the keys and do whatever you need to do.
I'm trying to create an object which references a number of forms which I can JSON.stringify() to send through to a validation script with a single AJAX request, but I can't seem to properly name the array inside the object, which should be an incrementing count as the number of arrays (forms) increases.
i.e.
var images = new Object();
var i = 0;
// loop through every form
$('form').each(function() {
var form = $(this);
images[i].name = form.find('input[name="name"]').val();
images[i].description = form.find('textarea[name="description"]').val();
// etc.
i++;
});
So, when complete after say two to three iterations (that is, it's gone through two-three forms), I have a Javascript object similar to this (written in pseudocode, I'm not exactly too sure how it's actually outputted):
images {
0 {
name : 0thImageNameValueHere,
description : 0thImageDescripValueHere,
etc : etc
}
1 {
name : 1stImageNameValueHere,
description : 1stImageDescripValueHere,
etc : etc
}
}
But, right now, Firebug is giving me a SyntaxError: missing ; before statement error, centered around this line:
images[i].name = form.find('input[name="name"]').val();
Now, I can change the 'value' of images[i].name to anything I like (images[i].name = 'yes') and I still get the same error. Syntactically I'm not missing any semi-colons, so it can't be that. Is it possible I'm not declaring my object correctly?
Images is an array ([]). Your syntax does not comply with this situation (you expect an object). Create an object for each item in the array, then you can assign values to the attributes of this object.
Also, you can just make use of the index parameter provided by jQuery, you don't have to create your own iterator.
This does what you want:
var images = []; // create an array
$('form').each(function( index ) {
var form = $(this);
// create object with {} object notation
var image = {
name: form.find('input[name="name"]').val(),
description: form.find('textarea[name="description"]').val()
};
images[index] = image; // append object in array position index;
}
See for more info on objects the JSON WIKI.
See for more info on arrays W3Schools.
I don't know about any missing semi colon, but you need to create an object at images[i] before you assign any properties on it. Ie try this:
images[i] = {
name: get('input[name="name"]').val(),
description: get('textarea[name="description"]').val()
};
You can also use the index parameter supplied by each():
$('form').each(function(i) { ... }