Javascript DataTable unknown parameter '0' for row 0, column 0? - javascript

my datatable gives me that error. (Requested unknown parameter '0' for row 0, column 0. For more information about this error, please see http://datatables.net/tn/4). how can i change that ? In DataTable i can see the rows but not data text .enter image description here
how can i fix this ?
My Html
<table id="callback_table" class="table manage_table" style="width: 100%;">
<thead id="callbackTable">
<tr>
<th>#ResourceManager.GetResource("Id")</th>
<th>#ResourceManager.GetResource("CallbackDate")</th>
<th style="width: 200px">#ResourceManager.GetResource("PointExpiryDate")</th>
<th style="width: 200px">#ResourceManager.GetResource("Point")</th>
<th>#ResourceManager.GetResource("TaskId")</th>
<th>#ResourceManager.GetResource("CallbackType")</th>
<th>#ResourceManager.GetResource("TaskName")</th>
<th>#ResourceManager.GetResource("Status")</th>
</tr>
</thead>
<tbody id="tdata">
</tbody>
</table>
My JS
var jsonData;
$.ajax({
url: '/History/GetCallbackHistory?' + "UserId" + "=" + document.getElementById("callbackuserid").value ,
type: 'GET',
success: function (data, textStatus, jqXHR) {
console.log(data);
}
});
$(document).ready(function () {
$('#callback_table').DataTable({
"ajax": {
"url": '/History/GetCallbackHistory?' + "UserId" + "=" + document.getElementById("callbackuserid").value,
"type": "GET",
"dataSrc": function (json) {
console.log(json);
return json;
}
}
});
});
My JSON
[
{
"Id": 6,
"TaskId": 302,
"Point": 4,
"DateCallback": "30-05-2020 12:02:29",
"DateEnd": "30-05-2020 12:02:29",
"callbackId": 2,
"Status": 1,
"callbackStatus": 0,
"phoneNumber": null,
"Task_name": ""
},
{},
{
"Id": 8,
"TaskId": 6459,
"Point": 10,
"DateCallback": "19-02-2021 14:25:08",
"DateEnd": "21-03-2021 14:25:08",
"callbackId": 2,
"Status": 1,
"callbackStatus": 0,
"phoneNumber": null,
"Task_name": ""
},
{
"Id": 9,
"TaskId": 6459,
"Point": 10,
"DateCallback": "19-02-2021 15:32:30",
"DateEnd": "21-03-2021 15:32:30",
"callbackId": 2,
"Status": 1,
"callbackStatus": 0,
"phoneNumber": null,
"Task_name": ""
},
{
"Id": 37,
"TaskId": 6784,
"Point": 5,
"DateCallback": "01-04-2021 12:58:49",
"DateEnd": "11-04-2021 19:06:44",
"callbackId": 8,
"Status": 1,
"callbackStatus": 0,
"phoneNumber": null,
"Task_name": ""
}
]

Related

HTML / JSON / Javascript / AJAX

i've tried to display some things from JSON into a localhost site ( "market_hash_name" and "image") but its only printing me one out of about 43 results on the site but in the console its printing all the elements.
i've used the " document.getElementById " to display it on the html site.
my question is:
Is there any kind of loop i can use to display all the market_hash_names and image on the html site?
<html>
<head>
<title>Inventory</title>
</head>
<body>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script>
$.ajax({
url: 'inventory.json',
dataType: 'json',
type: 'get',
contentType: "text/html; charset=UTF-8",
cache: false,
success: function(data){
$(data.data.steam_inventory.items).each(function(index, value){
var marketname = value.market_hash_name
var urlicon = value.image
document.getElementById("outputIconURL").src = urlicon
document.getElementById("outputName").innerHTML = marketname
console.log(marketname, "\n", urlicon)
});
}
});
</script>
<img id=outputIconURL width="350" height="300">
<p id=outputName></p>
</body>
</html>
here is the JSON File but only 100 out of 4000 lines of code. should be enough.
{
"status": "success",
"data": {
"app_id": "730",
"context_id": "2",
"steam_inventory": {
"status": "success",
"fresh_or_cached": "cached",
"total_items": 45,
"items": [
{
"app_id": "730",
"context_id": "2",
"number_of_items": 2,
"item_ids": [
"20276818150",
"20224634211"
],
"asset_ids": [
"20276818150",
"20224634211"
],
"class_id": "3761545285",
"instance_id": "0",
"market_hash_name": "Prisma 2 Case",
"suggested_price": "0.03",
"item_type": "Container",
"item_class": null,
"item_rarity": null,
"item_weapon": null,
"item_quality": "Base Grade",
"item_itemset": "The Prisma 2 Collection",
"image": "https://steamcommunity-a.akamaihd.net/economy/image/-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXU5A1PIYQNqhpOSV-fRPasw8rsUFJ5KBFZv668FFU1nfbOIj8W7oWzkYLdlPOsMOmIk2kGscAj2erE99Sn2AGw_0M4NW2hIYOLMlhpcmY0CRM/256fx256f",
"inspectable": false,
"inspect_link": null,
"phase": null,
"tags": {
"type": "Container",
"collection": "The Prisma 2 Collection",
"category": "Normal",
"quality": "Base Grade"
},
"has_buy_orders": false,
"recent_sales_info": null,
"stickers": null,
"fraud_warnings": [
[],
[]
],
"is_listing_allowed": false
},
{
"app_id": "730",
"context_id": "2",
"number_of_items": 1,
"item_ids": [
"20276522620"
],
"asset_ids": [
"20276522620"
],
"class_id": "469444882",
"instance_id": "302028390",
"market_hash_name": "Tec-9 | Urban DDPAT (Field-Tested)",
"suggested_price": "0.04",
"item_type": "Pistol",
"item_class": null,
"item_rarity": null,
"item_weapon": "Tec-9",
"item_quality": "Consumer Grade",
"item_itemset": "The Bank Collection",
"image": "https://steamcommunity-a.akamaihd.net/economy/image/-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXH5ApeO4YmlhxYQknCRvCo04DEVlxkKgpoor-mcjhoyszMdS1D-OOjhoK0mvLwOq7c2D4B6pwijLiXpt6s3lDkrkJvZG-hLI7Ee1M7YVmC8gO-kunrjZK1tJXXiSw0uDynv1g/256fx256f",
"inspectable": true,
"inspect_link": "steam://rungame/730/76561202255233023/+csgo_econ_action_preview%20S76561198248775632A%asset_id%D7936680248821929362",
"phase": null,
"tags": {
"type": "Pistol",
"weapon": "Tec-9",
"collection": "The Bank Collection",
"category": "Normal",
"quality": "Consumer Grade",
"exterior": "Field-Tested"
},
"has_buy_orders": false,
"recent_sales_info": null,
"stickers": null,
"fraud_warnings": [
[]
],
"is_listing_allowed": false
},
{
"app_id": "730",
"context_id": "2",
"number_of_items": 1,
"item_ids": [
"20215185457"
],
"asset_ids": [
"20215185457"
],
"class_id": "4141779477",
"instance_id": "519977179",
"market_hash_name": "Desert Eagle | The Bronze (Factory New)",
"suggested_price": "0.34",
"item_type": "Pistol",
"item_class": null,
"item_rarity": null,
"item_weapon": "Desert Eagle",
"item_quality": "Industrial Grade",
"item_itemset": "The Control Collection",
"image": "https://steamcommunity-a.akamaihd.net/economy/image/-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXH5ApeO4YmlhxYQknCRvCo04DEVlxkKgposr-kLAtl7PLFTjNX4d6zhpO0leX7PaHUqWdY781lxLCZo9yh3gW3_hJqNj_2Jo6TelI8NQmErlPsyLq90ZPvtJnLm3Ux6CA8pSGK8qELUuc/256fx256f",
"inspectable": true,
"inspect_link": "steam://rungame/730/76561202255233023/+csgo_econ_action_preview%20S76561198248775632A%asset_id%D16890227741044942403",
"phase": null,
"tags": {
"type": "Pistol",
"weapon": "Desert Eagle",
"collection": "The Control Collection",
"category": "Normal",
"quality": "Industrial Grade",
"exterior": "Factory New"
},
"has_buy_orders": false,
"recent_sales_info": {
"hours": "18.86",
"average_price": "0.27"
},
"stickers": null,
"fraud_warnings": [
[]
],
"is_listing_allowed": true
},
You are using innerHTML so your content is override and only last one display .Instead you can generate htmls in your each loop and append same to some div .
Demo Code :
var data = {
"status": "success",
"data": {
"steam_inventory": {
"items": [{
"market_hash_name": "Prisma 2 Case",
"image": "https://steamcommunity-a.akamaihd.net/economy/image/-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXU5A1PIYQNqhpOSV-fRPasw8rsUFJ5KBFZv668FFU1nfbOIj8W7oWzkYLdlPOsMOmIk2kGscAj2erE99Sn2AGw_0M4NW2hIYOLMlhpcmY0CRM/256fx256f",
},
{
"market_hash_name": "Tec-9 | Urban DDPAT (Field-Tested)",
"image": "https://steamcommunity-a.akamaihd.net/economy/image/-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXH5ApeO4YmlhxYQknCRvCo04DEVlxkKgpoor-mcjhoyszMdS1D-OOjhoK0mvLwOq7c2D4B6pwijLiXpt6s3lDkrkJvZG-hLI7Ee1M7YVmC8gO-kunrjZK1tJXXiSw0uDynv1g/256fx256f",
}
]
}
}
}
$(data.data.steam_inventory.items).each(function(index, value) {
var marketname = value.market_hash_name
var urlicon = value.image
//append datas
$("#result").append("<div><img class='outputIconURL' src='" + urlicon + "' width='350' height='300'><p class='outputName'>" + marketname + "</p></div>")
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="result">
<!--result will cme here--->
</div>

How to load json foriegn key data to jquery datatable

This is how my JSON data is getting using the url.
[
{
"id": 1,
"fullName": "Menushi",
"email": "menushi#gmail.com",
"contact": "04567383",
"department": {
"id": 1,
"departmentName": "Computing and Information System(CIS)",
"description": "This department is regarding computer science ",
"active": true
},
"imageUrl": "LCR438D8E9C68",
"active": true,
"file": null,
"address": "Polonnaruwa"
},
I want to display the department name in the Jsondata table.Below shows the part of the javascript file.Department object is in onetoone relationship.I want to display department object data also in the table.
$table.DataTable({
pageLength: 5,
lengthMenu: [[3, 5, 10, -1], ["3 Records", "5 Records", "10 Records", "All"]],
ajax: {
url: jsonUrl,
dataSrc: ''
},
columns: [
{
data : 'imageUrl',
mRender : function(data,type,row){
return '<img src="'+window.root+'/resources/images/'+data+'.jpg" class="dataTableImg">';
}
},
{
data: 'fullName'
},
{
data: 'address'
},
{
data: 'email'
},
{
data: 'department.departmentName',
},
{
data: 'contact'
}
I have used the above way to display the department name in my javascript file..But it display nothing.How I can over come this issue?

Datatable binds only half of the data

I am trying to bind data to a jQuery Datatable but it only binds half of it. I checked the AJAX call; it returns success and I am getting data properly. However the same data is not binding to the grid.
My data:
{
"draw": "1",
"recordsFiltered": 1,
"recordsTotal": 1,
"data": [{
"TitleName": "w",
"CustomerName": "q",
"ServiceType": "r",
"MailClass": "w",
"ProcessingCategory": "a",
"Origin": "a",
"IsActive": true,
"DateModified": "1/31/2018 12:00:00 AM",
"ContentTitleId ": 1,
"MailClassId ": 1,
"ProcessingCategoryId ": 1,
"ServiceTypeId ": 1,
"TransportationTypeId ": 1
}]
}
$(document).ready(function () {
$('#example').DataTable({
processing: true,
serverSide: true,
ajax: {
url: "/ContentTitleManagement/OverviewPageWithServerSidePagination",
type: "GET",
datatype: "json",
// success: function (result) {
// console.log("something");
// }
},
columns: [
{ "data": "TitleName" },
{ "data": "CustomerName" },
{ "data": "ServiceType" },
{ "data": "MailClass" },
{ "data": "ProcessingCategory" },
{ "data": "Origin" },
{ "data": "DateModified" },
{ "data": "IsActive" },
// Data gets bound up to here
// { "data": "ContentTitleId" },
// { "data": "MailClassId" },
// { "data": "ProcessingCategoryId" },
// { "data": "ServiceTypeId" },
// { "data": "TransportationTypeId" }
]
});
});
<table id="example">
<thead>
<tr>
<th>TITLE NAME</th>
<th>CUSTOMER NAME</th>
<th>SERVICE<br />TYPE</th>
<th>MAIL<br />CLASS</th>
<th>PROCESSING<br />CATEGORY</th>
<th>ORIGIN</th>
<th>DATE<br />MODIFIED</th>
<th>IS<br />ACTIVE</th>
<th>Content Title Id</th>
<th>Mail Class Id</th>
<th>Processing Category Id</th>
<th>Service Type Id</th>
<th>Transportation Type Id</th>
</tr>
</thead>
</table>
The above code works file as long as I keep those columns commented in columns section of the datatable method. But if I uncomment then it throws below error
DataTables warning: table id=example - Ajax error. For more information about this error, please see http://datatables.net/tn/7
You have spaces in your 5 last identifiers in data:
"IsActive": true,
"DateModified": "1/31/2018 12:00:00 AM",
"ContentTitleId ": 1, <-- space at the end
"MailClassId ": 1,
"ProcessingCategoryId ": 1,
"ServiceTypeId ": 1,
"TransportationTypeId ": 1
You have to change it to:
"IsActive": true,
"DateModified": "1/31/2018 12:00:00 AM",
"ContentTitleId": 1,
"MailClassId": 1,
"ProcessingCategoryId": 1,
"ServiceTypeId": 1,
"TransportationTypeId": 1

How to check if all numbers in an object are within a certain range?

One of the features I'd like to include in my current JS/jQuery project is to allow users to export and import their saved data. The import/export data is just one big object being ran through JSON.stringify and JSON.parse, and implementing a basic version of that has worked well, but I'd like to validate the imported data to make sure it will work(this is less about working as JavaScript and more about working within the rules of the game I'm making).
I'd like to come up with a more efficient script to validate this big complicated object. The only parts of the object I'm concerned with are the numbers, but it also includes strings, arrays, nested objects. Some of the nested objects include numbers I'm concerned with, but also more other junk including even further nested objects. Currently, I'm using jQuery's each() function to loop over each subsection of the object and evaluate it, but this requires me to write an each function for each subsection I'm concerned with.
How can I feed a function this whole object and have it look at just the numbers to see if they're greater than or less than a set value?
Edit: Pasting the object here, the goal is to check if all of the numbers. Some need to be between 0 and 3, some need to be between 0 and 9.
{
"meta": {
"id": 2,
"name": "Test",
"concept": "test description"
},
"coreAttributes": {
"Strength": 3,
"Finesse": 1,
"Perception": 9,
"Stamina": 1,
"Agility": 1,
"Wits": 1,
"Willpower": 1,
"Charisma": 1,
"Intelligence": 1
},
"skills": {
"Toughness": ["Strength", "STR", 0],
"Stealth": ["Finesse", "FIN", 0],
"Alertness": ["Perception", "PER", 3],
"Investigate": ["Perception", "PER", 0],
"Athletics": ["Agility", "AGI", 0],
"Drive": ["Wits", "WIT", 0],
"Survival": ["Wits", "WIT", 0],
"Guts": ["Willpower", "WIL", 4],
"Hardware": ["Intelligence", "INT", 0],
"Humanities": ["Intelligence", "INT", 0],
"Medicine": ["Intelligence", "INT", 0],
"Science": ["Intelligence", "INT", 0],
"Software": ["Intelligence", "INT", 0],
"Charm": ["Charisma", "CHA", 0],
"Manipulate": ["Charisma", "CHA", 0]
},
"unrolledSkills": {
"Contacts": 0,
"Languages": 0,
"Resources": 0
},
"combatSkills": {
"Unarmed": ["Strength", "STR", 0],
"Defense": ["Finesse", "FIN", 0],
"Melee": ["Finesse", "FIN", 0],
"Firearms": ["Perception", "PER", 0],
"Ballistics": ["Perception", "PER", 0],
"Initiative": ["Wits", "WIT", 0]
},
"attacks": {},
"status": {
"currentEndurance": 4,
"currentSpeed": 4,
"currentEntanglement": 4,
"body": {
"upper": {
"wounds": 0,
"armor": ["", 0]
},
"lower": {
"wounds": 0,
"armor": ["", 0]
},
"main": {
"wounds": 0,
"armor": ["", 0]
},
"off": {
"wounds": 0,
"armor": ["", 0]
},
"legs": {
"wounds": 0,
"armor": ["", 0]
}
}
},
"styles": {
"classes": {
"Strength": {
"core": 0,
"spec1": 0,
"spec2": 0,
"spec3": 0,
"aux1": {
"skill": false,
"name": "",
"value": 0
},
"aux2": {
"skill": false,
"name": "",
"value": 0
},
"aux3": {
"skill": false,
"name": "",
"value": 0
}
},
"Finesse": {
"core": 0,
"spec1": 0,
"spec2": 0,
"spec3": 0,
"aux1": {
"skill": false,
"name": "",
"value": 0
},
"aux2": {
"skill": false,
"name": "",
"value": 0
},
"aux3": {
"skill": false,
"name": "",
"value": 0
}
},
"Perception": {
"core": 0,
"spec1": 0,
"spec2": 0,
"spec3": 0,
"aux1": {
"skill": false,
"name": "",
"value": 0
},
"aux2": {
"skill": false,
"name": "",
"value": 0
},
"aux3": {
"skill": false,
"name": "",
"value": 0
}
},
"Stamina": {
"core": 0,
"spec1": 0,
"spec2": 0,
"spec3": 0,
"aux1": {
"skill": false,
"name": "",
"value": 0
},
"aux2": {
"skill": false,
"name": "",
"value": 0
},
"aux3": {
"skill": false,
"name": "",
"value": 0
}
},
"Agility": {
"core": 0,
"spec1": 0,
"spec2": 0,
"spec3": 0,
"aux1": {
"skill": false,
"name": "",
"value": 0
},
"aux2": {
"skill": false,
"name": "",
"value": 0
},
"aux3": {
"skill": false,
"name": "",
"value": 0
}
},
"Wits": {
"core": 0,
"spec1": 0,
"spec2": 0,
"spec3": 0,
"aux1": {
"skill": false,
"name": "",
"value": 0
},
"aux2": {
"skill": false,
"name": "",
"value": 0
},
"aux3": {
"skill": false,
"name": "",
"value": 0
}
},
"Willpower": {
"core": 0,
"spec1": 0,
"spec2": 0,
"spec3": 0,
"aux1": {
"skill": false,
"name": "",
"value": 0
},
"aux2": {
"skill": false,
"name": "",
"value": 0
},
"aux3": {
"skill": false,
"name": "",
"value": 0
}
},
"Charisma": {
"core": 0,
"spec1": 0,
"spec2": 0,
"spec3": 0,
"aux1": {
"skill": false,
"name": "",
"value": 0
},
"aux2": {
"skill": false,
"name": "",
"value": 0
},
"aux3": {
"skill": false,
"name": "",
"value": 0
}
},
"Intelligence": {
"core": 0,
"spec1": 0,
"spec2": 0,
"spec3": 0,
"aux1": {
"skill": false,
"name": "",
"value": 0
},
"aux2": {
"skill": false,
"name": "",
"value": 0
},
"aux3": {
"skill": false,
"name": "",
"value": 0
}
}
},
"arcane": {
"restoration": 0,
"evocation": 0,
"abjuration": 0,
"sublimation": 0,
"paradigm": 0,
"telepathy": 0,
"shift": 0,
"electromagnetism": 0,
"gravitonertia": 0,
"chromodynamism": 0,
"technology": 0
},
"extension": {
"avatar": 0,
"proxy": 0,
"permanence": 0
}
},
"addenda": {}
}
The below uses recursion to search all keys in a multidimensional object for any numbers lower or greater than the supplied numbers.
Simply call the function like checkObject(myStuff, 30, 60); passing in your object, your lowest allowed number, and your highest allowed number
var myStuff = { "results": [
{
"ACL": {
"7UeILO5tC4": {
"count": "45",
"read": true
},
"role:Leads": {
"count": "12",
"read": true,
"write": true
}
},
"createdAt": "2014-12-16T22:04:46.338Z",
"finishDate": "12%2F16%2F2014",
"finishTime": "16%3A4%3A44",
"objectId": "tVldoxxdCB",
"passFail": "Pass",
"passingPercentage": "56",
"passingPoints": "34",
"questions": "21",
"quizName": "Name",
"quizType": "Flights",
"teamMember": "Jame Fellows",
"ttlPossiblePoints": "59",
"updatedAt": "2014-12-16T22:04:46.338Z",
"userName": "Jame.Fellows",
"userPercentage": "95",
"userPoints": "20",
"userRightAnswers": "57"
},
{
"ACL": {
"7UeILO5tC4": {
"count": "44",
"read": true
},
"role:Leads": {
"count": "12",
"read": true,
"write": true
}
},
"createdAt": "2014-12-16T22:04:46.338Z",
"finishDate": "12%2F16%2F2014",
"finishTime": "16%3A4%3A44",
"objectId": "tVldoxxdCB",
"passFail": "Pass",
"passingPercentage": "90",
"passingPoints": "87",
"questions": "21",
"quizName": "Name",
"quizType": "Flights",
"teamMember": "Jame Fellows",
"ttlPossiblePoints": "79",
"updatedAt": "2014-12-16T22:04:46.338Z",
"userName": "Jame.Fellows",
"userPercentage": "76",
"userPoints": "20",
"userRightAnswers": "45"
},
{
"ACL": {
"7UeILO5tC4": {
"count": "45",
"read": true
},
"role:Leads": {
"count": "12",
"read": true,
"write": true
}
},
"createdAt": "2014-12-16T22:04:46.338Z",
"finishDate": "12%2F16%2F2014",
"finishTime": "16%3A4%3A44",
"objectId": "tVldoxxdCB",
"passFail": "Pass",
"passingPercentage": "90",
"passingPoints": "19",
"questions": "21",
"quizName": "Name",
"quizType": "Flights",
"teamMember": "Jame Fellows",
"ttlPossiblePoints": "21",
"updatedAt": "2014-12-16T22:04:46.338Z",
"userName": "Jame.Fellows",
"userPercentage": "95",
"userPoints": "20",
"userRightAnswers": "20"
}
] };
// track how many invalid numbers we find
var hasInvalidData=0;
// call our checkObject() function, pass it
// your object, your lowest allowed number, your highest allowed number
checkObject(myStuff, 30, 60);
if(hasInvalidData > 0){
alert(hasInvalidData + ' invalid numbers were found')
}
function checkObject(object, low, high){
// loop through each property of the object
for (var property in object) {
// make sure it's a real property and not inherited
if (object.hasOwnProperty(property)) {
//get the value of the current property
var value = object[property];
// if this propery is itself an object,
// call this function recursively
if(typeof object[property] == "object" && typeof object[property] !== null){
checkObject(object[property], low, high)
}
else{
// if it's not an object
// check if it a a number and not true or false
// which wihich isNaN sees as 1 and 0
if( !isNaN(value) && typeof value != "boolean"){
console.log(value);
if(value < low){
console.log('^ this value is too small ^');
hasInvalidData++;
}
if(value > high){
console.log('^ this value is too large ^');
hasInvalidData++;
}
}
}
}
}
}
What you're looking for is actually very simple – recursion.
The below code checks if all numbers are larger than or equal to 2 and will return false on first non-matching number.
var x = {
b: 5,
c: {
d: 3,
e: [1, 2, 3],
f: function() {}
},
g: function() {}
};
var recurse = function(a) {
var s = true;
for (prop in a) {
switch (typeof a[prop]) {
case "number":
//Check for conditions here
console.log("found number " + a[prop]);
if (a[prop] < 2) {
return false;
}
break;
case "object":
if (a[prop] !== null) {
s = s && recurse(a[prop]);
}
break;
default:
break;
}
}
return s;
}
recurse(x);
Here is an iterative solution:
var x = {
b: 5,
c: {
d: 3,
e: [1, 2, 3],
f: function() {}
},
g: function() {}
};
function check (obj) {
var queue = [obj];
while (queue.length > 0) {
var current = queue.shift();
for (var prop in current) {
if (!current.hasOwnProperty(prop)) continue;
switch (typeof(current[prop])) {
case "number":
// check for conditions here
if (current[prop] < 2) {
return false;
}
break;
case "object":
if (current[prop] !== null) {
queue.push(current[prop]);
}
break;
default:
break;
}
}
}
return true;
}
alert(check(x));
It's a bit faster since it can finish early
Here you go, you only need this: (it also has some fancy visualisation :P)
function traverse(obj, callback, level) {
for (var i in obj) {
if (!obj.hasOwnProperty(i)) continue;
callback.apply(this, [i, obj[i], level||""]);
(obj[i] !== null && typeof(obj[i])=="object") && traverse(obj[i],callback,(level||"")+" ");
}
}
// it is called like this
traverse(obj, valueCheck);
//obj - is your object as in your question
//valueCheck(key, val, level) - is your own function to check the value
An exemplary valueCheck() function might be as follows
function valueCheck(key, val, level) {
// proceed to check only if the value is a number
if (!isNaN(parseFloat(val)) && isFinite(val)) {
var isError = ! ((0 <= val) && (val <= 9));
console.log(level + key + " : " + val + (isError && " ----------------------- VALUE ERROR" || ""));
} else {
// if it's a new object, print shiny "-" at the begining
(typeof val == "object") && console.log(Array(1+level.length).join("-") + key);
}
}

Why does queryAsync() result in added meta data?

I used queryAsync() as prescribed by an answer to a question, and it works, but it adds lots of extra meta data to my query result, which is otherwise a straightforward query.
Here's what I'm using to process/execute the query and log the result:
var retrieveSettings = Promise.method(function (username, connection) {
console.log('User ' + username + ' retrieving settings...');
var q = 'select * from sales_settings';
return connection.queryAsync(q).then(function (rows, fields) {
list = [];
for (x = 0; x < rows.length; x++) {
list.push(rows[x]);
}
//console.log('Settings: ' + JSON.stringify(list, null, 4));
return list;
});
});
and here is the result that is logged:
Settings: [
[
{
"group_name": "add_auto",
"commission_rate": 0,
"monthly_req": 0,
"category_name": "Auto",
"commission_type": "none",
"group_title": "Added Auto"
},
{
"group_name": "add_fire",
"commission_rate": 0,
"monthly_req": 0,
"category_name": "Fire",
"commission_type": "none",
"group_title": "Added Fire"
},
{
"group_name": "bank_dep",
"commission_rate": 25,
"monthly_req": 0,
"category_name": "Bank",
"commission_type": "static",
"group_title": "Bank Deposit"
},
{
"group_name": "bank_loan",
"commission_rate": 75,
"monthly_req": 8,
"category_name": "Bank",
"commission_type": "static",
"group_title": "Bank Loan"
},
{
"group_name": "health",
"commission_rate": 0.084,
"monthly_req": 4,
"category_name": "Health",
"commission_type": "premium",
"group_title": "Health App"
},
{
"group_name": "life",
"commission_rate": 0.084,
"monthly_req": 8,
"category_name": "Life",
"commission_type": "premium",
"group_title": "Life App"
},
{
"group_name": "new_auto",
"commission_rate": 0.03,
"monthly_req": 32,
"category_name": "Auto",
"commission_type": "rate",
"group_title": "Raw New Auto"
},
{
"group_name": "new_fire",
"commission_rate": 0.03,
"monthly_req": 20,
"category_name": "Fire",
"commission_type": "rate",
"group_title": "Raw New Fire"
}
],
[
{
"catalog": "def",
"db": "officeball",
"table": "sales_settings",
"orgTable": "sales_settings",
"name": "group_name",
"orgName": "group_name",
"filler1": [
12
],
"charsetNr": 33,
"length": 135,
"type": 253,
"flags": 20483,
"decimals": 0,
"filler2": [
0,
0
],
"zeroFill": false,
"protocol41": true
},
{
"catalog": "def",
"db": "officeball",
"table": "sales_settings",
"orgTable": "sales_settings",
"name": "commission_rate",
"orgName": "commission_rate",
"filler1": [
12
],
"charsetNr": 63,
"length": 13,
"type": 246,
"flags": 4097,
"decimals": 3,
"filler2": [
0,
0
],
"zeroFill": false,
"protocol41": true
},
{
"catalog": "def",
"db": "officeball",
"table": "sales_settings",
"orgTable": "sales_settings",
"name": "monthly_req",
"orgName": "monthly_req",
"filler1": [
12
],
"charsetNr": 63,
"length": 11,
"type": 3,
"flags": 4097,
"decimals": 0,
"filler2": [
0,
0
],
"zeroFill": false,
"protocol41": true
},
{
"catalog": "def",
"db": "officeball",
"table": "sales_settings",
"orgTable": "sales_settings",
"name": "category_name",
"orgName": "category_name",
"filler1": [
12
],
"charsetNr": 33,
"length": 135,
"type": 253,
"flags": 4097,
"decimals": 0,
"filler2": [
0,
0
],
"zeroFill": false,
"protocol41": true
},
{
"catalog": "def",
"db": "officeball",
"table": "sales_settings",
"orgTable": "sales_settings",
"name": "commission_type",
"orgName": "commission_type",
"filler1": [
12
],
"charsetNr": 33,
"length": 135,
"type": 253,
"flags": 4097,
"decimals": 0,
"filler2": [
0,
0
],
"zeroFill": false,
"protocol41": true
},
{
"catalog": "def",
"db": "officeball",
"table": "sales_settings",
"orgTable": "sales_settings",
"name": "group_title",
"orgName": "group_title",
"filler1": [
12
],
"charsetNr": 33,
"length": 72,
"type": 253,
"flags": 4097,
"decimals": 0,
"filler2": [
0,
0
],
"zeroFill": false,
"protocol41": true
}
]
]
Why is this unusual meta data being added to my query result?
It looks like you are using bluebird, in that case you can use .spread:
var retrieveSettings = Promise.method(function (username, connection) {
console.log('User ' + username + ' retrieving settings...');
var q = 'select * from sales_settings';
return connection.queryAsync(q).spread(function (rows, fields) {
list = [];
for (x = 0; x < rows.length; x++) {
list.push(rows[x]);
}
//console.log('Settings: ' + JSON.stringify(list, null, 4));
return list;
});
});
The problem with the mysql module is that it doesn't conform to the node js callback standard which is (err, result). Instead it uses (err, result1, result2). Because functions can only throw one exception or return one value, bluebird returns an array of [result1, result2] to avoid information loss.
.spread is like .then except it assumes the fulfulliment value is an array and spreads the array's values over the arguments.
The standard callback from mysql's query() returns both a rows and fields. The asynch wrapper you are using (for example if you Q.denodeify()) is only returning a single thing, so for callbacks with multiple parameters it returns an array of [param1,param2] in this case [rows,fields].
Related to this, your function inside the then needs to accept only one parameter (which would be this array of [rows,fields]).
See the second portion of my answer to this question as an illustration.
Your code should thus be something like:
var retrieveSettings = Promise.method(function (username, connection) {
console.log('User ' + username + ' retrieving settings...');
var q = 'select * from sales_settings';
return connection.queryAsync(q).then(function (results) {
var rows = results[0]; // get the rows
var fields = results[1]; // don't really care, but just for illustration
list = [];
for (x = 0; x < rows.length; x++) {
list.push(rows[x]);
}
//console.log('Settings: ' + JSON.stringify(list, null, 4));
return list;
});
});
And actually, for the above code, there's no reason your entire callback can't just be:
return connection.queryAsync(q).then(function (results) {
return results[0]; // get the rows
});

Categories