Hello Friends on StackOverflow:
I am struggling to find what is causing a nested jQuery function to return values of 'undefined' or '[object Object]'. I have commented the location of the first function, which contains the function call. I can see from my research into this subject I am not alone in this perplexing issue. Depending on which bit of code I use inside the nested jQuery function inside the second "getAttributeValue" function I get different results. Stackoverflow helpers can see the various permutations of the code I have been trying, but are commented out for debugging, etc. The 'alert' method returns perfect clear data the way I want it. The others return nothing, 'undefined', or '[object Object]', but never the perfect clear data I want. I have been at this long enough to know I need help.
The data source is a web api / web service providing JSON data.
Here is the code:
//# This is the primary function that gathers data from a web api / web service:
$(document).ready(function () {
$("#loadData").click(function () {
$.get(url, function (data) {
var myHTMLDataTable = "<table class='table table-striped table-hover'>";
myHTMLDataTable = myHTMLDataTable + "<tr><th>WebId</th><th>Attributes</th><th>Values</th></tr>";
for (i = 0; i < data.Items.length; i++) {
myHTMLDataTable = myHTMLDataTable + "<tr>";
myHTMLDataTable = myHTMLDataTable + "<td class='col-sm-1'>" + (data.Items[i].WebId) + "</td>";
myHTMLDataTable = myHTMLDataTable + "<td class='col-sm-1'>" + (data.Items[i].Name) + "</td>";
myHTMLDataTable = myHTMLDataTable + "<td class='col-sm-1'>"+ getAttributeValue(data.Items[i].WebId) + "</td>"; //~ function call here
myHTMLDataTable = myHTMLDataTable + "</tr>";
}
myHTMLDataTable = myHTMLDataTable + "</table>";
document.getElementById("myData").innerHTML = myHTMLDataTable;
});
});
});
//# This function returns a current value and uom for the target attribute:
function getAttributeValue(attributeWebId) {
var theEnvelopePlease = ""; //~ clear the variable
var atrbUrl = "https://<<The Target Web API Root Address>>";
var atrbPrefix = "streams/";
var atrbWebId = attributeWebId;
var atrbExtension = "/value";
//~ Concatenate the URL used to make the request
atrbUrl = atrbUrl + atrbPrefix + atrbWebId + atrbExtension;
// theEnvelopePlease = $.getJSON(atrbUrl, function (data) { data.Value });
return $.getJSON(atrbUrl, function (data) {
//return (data.Value) + " " + (data.UnitsAbbreviation);
//alert(data.Value + " " + data.UnitsAbbreviation);
//theEnvelopePlease = theEnvelopePlease + (data.Value) + " " + (data.UnitsAbbreviation);
(data.Value) + " " + (data.UnitsAbbreviation);
});
// return theEnvelopePlease;
}
the JSON data being retrieved by the nested jQuery function looks like this:
{
"Timestamp": "2015-06-03T22:22:00Z",
"Value": 89.660293579101563,
"UnitsAbbreviation": "%",
"Good": true,
"Questionable": false,
"Substituted": false
}
Perhaps there is a JQuery expert reviewing this who sees my mistakes easily. Your help is much appreciated.
UPDATE: because it has been requested I want to show what I get when I use console.log:
UPDATE: Hi @IronFlare: Thank you for your suggestion. I tried your suggestion with the revised function code as follows:
function getAttributeValue(attributeWebId) {
var theEnvelopePlease; //~ clear the variable
var atrbUrl = "https://<<The Target Web API Root Address>>";
var atrbPrefix = "streams/";
var atrbWebId = attributeWebId;
var atrbExtension = "/value";
//~ Concatonate the URL used to make the request
atrbUrl = atrbUrl + atrbPrefix + atrbWebId + atrbExtension;
$.getJSON(atrbUrl, function (data) {
theEnvelopePlease = (data.Value) + " " + (data.UnitsAbbreviation);
});
return theEnvelopePlease;
}
and the resulting data is 'undefined' (:-c)
=======================================================
Hi @IronFlare and thank you for your suggestion. I modified the function as follows:
function getAttributeValue(attributeWebId) {
var theEnvelopePlease; //~ clear the variable
var atrbUrl = "https://<<The Target Web API Root Address>>";
var atrbPrefix = "streams/";
var atrbWebId = attributeWebId;
var atrbExtension = "/value";
//~ Concatenate the URL used to make the request
atrbUrl = atrbUrl + atrbPrefix + atrbWebId + atrbExtension;
$.getJSON(atrbUrl, function (data) {
theEnvelopePlease = (data.Value) + " " + (data.UnitsAbbreviation);
console.log(data);
});
return theEnvelopePlease;
}
and here is a view of the results:
====================================================
UPDATE: For those who are following this thread I have attempted this permutation:
//# Stackoverflow permutation 03:
function getAttributeValue(attributeWebId) {
var theEnvelopePlease; //~ clear the variable
var atrbUrl = "https://<<The Target Web API Root Address>>";
var atrbPrefix = "streams/";
var atrbWebId = attributeWebId;
var atrbExtension = "/value";
//~ Concatenate the URL used to make the request
atrbUrl = atrbUrl + atrbPrefix + atrbWebId + atrbExtension;
theEnvelopePlease = $.getJSON(atrbUrl, function (data) {
console.log(data.Value) + " " + (data.UnitsAbbreviation);
return (data.Value) + " " + (data.UnitsAbbreviation);
});
return theEnvelopePlease;
}
and here is a view of the results:
For those who will follow this posting in the future I am pleased to provide the solution I finally found (5 days later). My key mistake centered on jQuery is essentially designed to manipulate existing HTML/DOM elements using CSS Selectors. In other languages such as C# you can procedurally call a function and get back a result and continue the rest of the program. In my previous attempts JQuery continuously returned 'undefined or '[object Object]' no matter what I tried. In this case I found my solution by first building "myHTMLDataTable" and applying a unique "id" attribute to the <td>
element I wanted to fill with values. So my revised code first builds the table using a for loop, and then populates the target table cell using a second loop that calls the now working function that returns the clear data I was desperately seeking. Here is the working code:
//# Stackoverflow SOLUTION:
//# This is the primary function that gathers data from a web api / web service:
$(document).ready(function () {
$("#loadData").click(function () {
//~ First Build the data Table:
$.get(url, function (data) {
var myHTMLDataTable = "<table class='table table-striped table-hover'>";
myHTMLDataTable = myHTMLDataTable + "<tr><th>WebId</th><th>Attributes</th><th>Values</th></tr>";
for (i = 0; i < data.Items.length; i++) {
myHTMLDataTable = myHTMLDataTable + "<tr>";
myHTMLDataTable = myHTMLDataTable + "<td class='col-sm-1'>" + (data.Items[i].WebId) + "</td>";
myHTMLDataTable = myHTMLDataTable + "<td class='col-sm-1'>" + (data.Items[i].Name) + "</td>";
myHTMLDataTable = myHTMLDataTable + "<td class='col-sm-1' id='" + (data.Items[i].WebId) + "'></td>"; //~ The target table cell using the unique 'WebId'
myHTMLDataTable = myHTMLDataTable + "</tr>";
}
myHTMLDataTable = myHTMLDataTable + "</table>";
document.getElementById("myData").innerHTML = myHTMLDataTable;
});
//~ Second Populate the target table cell by calling the 'getAttributeValue' function in a second for loop:
$.get(url, function (data) {
for (i = 0; i < data.Items.length; i++) {
getAttributeValue(data.Items[i].WebId);
}
});
});
});
//# This function returns a current value and uom for the target attribute directly into the target cell:
function getAttributeValue(attributeWebId) {
var atrbURL = "https://<<The Target Web API Root Address>>";
var atrbPrefix = "streams/";
var atrbWebId = attributeWebId;
var atrbExtension = "/value";
//~ Concatenate the URL used to make the request
atrbUrl = atrbURL + atrbPrefix + atrbWebId + atrbExtension;
$.getJSON(atrbUrl, function (data) {
var myInnerValue = "";
$.each(data, function (key, val) {
if (key == 'Value') {
myInnerValue = myInnerValue + val + " ";
}
if (key == 'UnitsAbbreviation') {
myInnerValue = myInnerValue + val;
}
});
$("#" + attributeWebId + "").text(myInnerValue);
});
}
And here is a screenshot of the results: