Nested JSON fetch using jQuery - javascript

I am trying to create an RSS Feed kind of Message display from Yammer.
<script type="text/javascript">
var cleanit = null;
$(document).ready(function(){ cleanit = setInterval('callYammer()', 50);});
function callYammer(){
clearInterval(cleanit);
$.getJSON("./yammer.feed?request=messages",function(json) {
var objYammer = $("#yammerFeed");
objYammer.html('');
$.each(json.messages, function(i, m) {
if(!m.replied_to_id && m.body.plain){
var data = "<li>" + m.body.plain;
$.getJSON("./yammer.feed?request=users&userid="+m.sender_id,function(jsonUser) {
//alert(jsonUser.full_name);
data = data + " - "+jsonUser.full_name;
});
data = data + "</li>";
objYammer.append(data);
}
});
});
return false;
}
</script>
I want to display Message along with it's Username.
But in the end, from firebug debugger, what I see is the inner JSON data is not getting appended as I expected.
Though the calls are hitting and data is coming from the call, the
data = " - "+jsonUser.full_name;
is getting executed after all JSON calls for Users.
How do I append Username from inner JSON call to main JSON data?

You call the lines
data = data + "</li>";
objYammer.append(data);
in the code following your inner getJSON AJAX call, but that probably results in these lines being executed before the AJAX request has finished. Put the code INTO the inner AJAX success function to make sure it is fired only after the result is available.
function callYammer(){
clearInterval(cleanit);
$.getJSON("./yammer.feed?request=messages",function(json) {
var objYammer = $("#yammerFeed");
objYammer.html('');
$.each(json.messages, function(i, m) {
if(!m.replied_to_id && m.body.plain){
var data = "<li>" + m.body.plain;
$.getJSON("./yammer.feed?request=users&userid="+m.sender_id,function(jsonUser) {
console.log('1:'+jsonUser.full_name);
data += " - "+jsonUser.full_name + "</li>";
objYammer.append(data);
console.log('2:'+data);
});
}
});
});
Edit:
Just added the console.log() statements. What do they return?

Related

How do I display JSON data to an HTML DOM Element after JSON.parse()?

I have two functions I am using to pull JSON from my server side to then display it to HTML.
The first function that pulls the data from the route handler is successfully pulling the data and parsing it successfully with JSON.parse() and displaying the needed information to the console without issue. I am not having and ajax or route handling issue...
Here is how I am dealing with the JSON first in my function called "projectInfo()":
projInfo = JSON.stringify(data);
console.log("DEBUG DONE WITH CAPTURING project_info DATA: " );
// This console.log() prints the JSON string
// successfully pulled from route handler
// var projInfo is a local string var declared in the scope of
// this first function
console.log("var projInfo: " + projInfo);
// parse JSON data in projInfo and store in string var p
// string var p is a local var declared inside of the scope
// of this function
p = JSON.parse(projInfo);
console.log("Parsed Project JSON: " + p.Project);
// update "Global" pInfo with the value of the JSON data for
// "Project" as needed
pInfo = p;
console.log("What is inside of pInfo???: " + pInfo);
// This last console.log prints [object Object] to console
// How do I pul the value out of this Object?
The second function calls the first function in order to update a global variable with the parsed JSON data that I need to then display the global variable's data to the DOM element that I am trying to display.
Here is how I am trying to update my global var with a JSON Object in my function called "loginFun()":
// Call projectInfo() in order to update Global pInfo
// with the needed project info
projectInfo();
// This console.log() prints nothing...?
console.log("projectInfo var data should be aa2: " + pInfo);
document.getElementById("userBar").style.display = "";
// This is where I try to Display pInfo in the DOM but I only get Undefined...?
document.getElementById("signedinas").innerHTML = "<font face=\"verdana\" size =\"4\" color=\"white\">Logged in as: " + username + " Project: " + pInfo + " </font>";
When I JSON.parse() the data in the first function I run a console.log() statement and I get the needed data to print from a variable local to the function I am getting my JSON with using ajax and I verify that the function is in fact doing what I need so that part is good up until I get the [object Object] output.
I am having issues when I call this function from my second function to then try to use the global variable which should have the data stored.
when I try to use the global variable with the needed data I get an 'undefined'...
I have also tried returning the data that has been parsed in the first function to then storehttps://codepen.io/lopezdp/pen/owKGdJ the value returned into a local variable in the second function but I still get 'undefined'.
If you would like to see the complete code for both functions I have put them on a CodePen to make it easier at:
https://codepen.io/lopezdp/pen/owKGdJ
How can I get my Project Data to display in my DOM element?
EDIT: The JSON Data that I am using looks like this:
{"User":"aa2","Owner":"aa2_role","Status":"locked","Port":"5432","Description":"Transferred from CFS01 on Jun29","Project":"aa2","Server":"localhost"}
I rewrote your login function like this and it worked for me. I also eliminated the projectInfo() function!
var allMn = [];
var tags = [];
var pInfo = '';
function loginFun() {
var username = document.getElementById('username').value;
var password = document.getElementById('password').value;
if (username == "" || password == "") {
alert("Required fields cannot be left blank.");
} else {
$.ajaxSetup({
cache: false
});
$.ajax({
type: 'GET',
url: 'http://139.169.63.170:' + port + '/login/' + username + "zlz" + password,
cache: false,
success: function (data) {
// NEED SUB ROUTINE HERE FOR AJAX CALL DPL
// Make async call to ccdd tool database to get new data
// This collects allMn[] data!!!
getMnJson();
// END SUB ROUTINE HERE
// Checks to make sure user is logged in if not
// the condition redirects user to loginFun()
if (data.search("HTTP ERROR: ") != -1) {
alert("Login Failed.");
document.getElementById('username').value = "";
document.getElementById('password').value = "";
document.getElementById('searchResults').innerHTML = "Login Failed";
document.getElementById('searchRBar').style.display = "";
loginFun();
} else {
login = 1;
// Call projectInfo() in order to update pInfo with the needed project info
//projectInfo();
var projInfo = '';
var p = '';
// Get all Mn Data on startup tp display in DOM -DPL
$.ajax({
type: 'GET',
url: 'http://139.169.63.170:' + port + '/role',
dataType: 'json',
cache: true,
success: function (data) {
// projInfo = JSON.stringify(data);
console.log("DEBUG DONE WITH CAPTURING project_info DATA: " );
// console.log("var projInfo: " + projInfo);
// parse JSON data in projInfo
p = data['Project']; //JSON.parse(projInfo);
console.log("Parsed Project JSON: " + p);
// update "Global" pInfo with the value of the JSON data for "Project" as needed
pInfo = p;
console.log("What is inside of pInfo???: " + pInfo);
document.getElementById("signedinas").innerHTML = "<font face=\"verdana\" size =\"4\" color=\"white\">Logged in as: " + username + " Project: " + pInfo + " </font>";
}
}).fail(function () {
alert("Login Failed.");
document.getElementById('username').value = "";
document.getElementById('password').value = "";
console.log("Error. /role data access Error.");
});
console.log("projectInfo var data should be aa2: " + pInfo);
document.getElementById("userBar").style.display = "";
// Display pInfo in the DOM
// document.getElementById("signedinas").innerHTML = "<font face=\"verdana\" size =\"4\" color=\"white\">Logged in as: " + username + " Project: " + pInfo + " </font>";
$("div.create").children().remove();
//-------------------------------------------------------------------END OF GLOBAL VARIABLES
$.ajaxSetup({
cache: false
});
// get table data from proxy server on port 7071 DPL
// NEED SUB ROUTINE HERE FOR AJAX CALL
// Make call to server-side code to reload JSON data into table from port 7071
pushJsonData();
// END SUB ROUTINE HERE!!!
// getTblJson();
}
}
}).fail(function () {
alert("Login Failed.");
document.getElementById('username').value = "";
document.getElementById('password').value = "";
console.log("Error. Need user Credentials");
});
}
}

getJSON not fetching data

My code below is not fetching data from data.js
The page works fine when the JSON data is hard coded into the page.
<head>
<title>Test Page</title>
<script>
function jsontest() {
var text;
$.getJSON("data.js", function(result) {
text = result;
});
var obj = JSON.parse(text);
document.getElementById("content").innerHTML =
obj.name + "<br>" +
obj.street + "<br>" +
obj.phone;
}
</script>
</head>
<body onload="jsontest();">
<h1>Testing Page</h1>
<p id="content"></p>
</body>
My data looks like this
{"name":"John Johnson","street":"Oslo West 16","phone":"555 1234567"}
Am I making a simple nooby mistake?
The first thing I notice is that you're using getJSON in sync mode. This won't work since it's executed asynchronous. You need to place your logic inside finish handler
function jsontest() {
var text;
$.getJSON("data.js", function(result) {
text = result;
var obj = JSON.parse(text);
document.getElementById("content").innerHTML =
obj.name + "<br>" +
obj.street + "<br>" +
obj.phone;
});
}
In your code, by the time you do
var obj = JSON.parse(text);
method getJSon didn't return yet so text contains the default value. It sends the request to the server and continue method flow without waiting for the result.
That's what the handler is for: to put logic that needs to be executed when request is complete.
$.getJSON is an async call - so when you try and run JSON.parse outside the callback, it won't work since the call is still in progress. Move your code to the callback and you'll be good:
function jsontest() {
$.getJSON("data.js", function(result) {
var text = result;
var obj = JSON.parse(text);
document.getElementById("content").innerHTML =
obj.name + "<br>" +
obj.street + "<br>" +
obj.phone;
});
//Anything after the `getJSON` call is executed immediately.
//$.getJSON is still in progress when these lines are executing
}
Javascript is single-threaded and non-blocking, as a result, while the ajax call is being executed the program counter will continue. Thus will be parsing something which is undefined.
If you put the code beneath the ajax callback inside it, it will work just fine.
You have to put your code inside the callback, or you wont have the text var populated:
function jsontest() {
var text;
$.getJSON("data.js", function(result) {
text = result;
var obj = JSON.parse(text);
document.getElementById("content").innerHTML =
obj.name + "<br>" +
obj.street + "<br>" +
obj.phone;
});
}

Cache each JSON search query with localStorage

THE PROMPT: We have a search that connects to an JSON API url. The search query is inside the url, and the API generates a new JSON file for every search term. We also cannot rely on the browser to cache for us, and we can't use PHP or server side caching; we need to use HTML5 LocalStorage (and we don't care that IE7 can't use it)
We need to cache every new JSON file for every new search. We want to cut down on requests per minute, so we want to use a cached version of the JSON file for repeated search terms.
WHERE I'M STUCK: What has made this difficult is caching a JSON file for each new/different search term. I have been able to cache the first search, but then all subsequent searches use the same cached JSON.
We need help rewriting this so each time a new search is made, it checks to see if the term was searched for previously and if so, grabs the corresponding JSON file. Then of course if the search term is new then cache a new JSON file for that specific search term.
WHAT I'VE TRIED: In my research I've seen a lot of very complicated solutions and I can't seem to get my head completely around all of it, some of these solutions almost worked, I think I just need a better explanation for this specific case.
I think this is the answer but I don't know how to apply it to my situation: jQuery deferred ajax cache
This is crazy and it almost works, it writes into the console when it recognizes that I've searched the same thing again, and it does stop a new request, but unfortunately the cached JSON isn't there, it returns no results.
Caching a jquery ajax response in javascript/browser
WHAT I HAVE SO FAR:
MY PSUEDO CODE:
var searchTerm = WHATEVER IS TYPED INTO THE SEARCHBOX
// The JSON file
var url = 'https://api.example.com/fake/json/path/{'+searchTerm+'}';
// Local Storage Caching Promise
var cachedData = localStorage.getItem("cachedData"),
def = $.Deferred();
if (!cachedData) {
def = $.getJSON(url, function(data) {
cachedData = data;
localStorage.setItem("cachedData", JSON.stringify(cachedData));
});
}
else{
cachedData = JSON.parse(cachedData);
def.resolve();
}
def.done(function() {
var resultHTML = '';
for(var i = 0; i < Object.keys(cachedData.things).length; i++){
$.each(cachedData, function(index, node){
resultHTML += '<li>'
resultHTML += '<h1>' + node[i].name + '</h1>';
resultHTML += '</li>';
});
}
$('div#results').html(resultHTML);
});
EXAMPLE JSON:
{
"things": [
{
"type": "thing",
"username": "randoguy",
"name": "name001",
},
{
"type": "thing2",
"username": "randoguy2",
"name": "name002",
},
...
Thank you #Ian for providing the hints to my answer!
var searchTerm = WHATEVER IS TYPED INTO THE SEARCHBOX;
// The JSON file
var url = 'https://api.example.com/fake/json/path/{'+searchTerm+'}';
// BABAM! Right here, SearchTerm + "-cachedData" gets unique cached data
var cachedData = localStorage.getItem(searchTerm + "-cachedData"),
def = $.Deferred();
if (!cachedData) {
def = $.getJSON(url, function(data) {
cachedData = data;
// BABAM! And here is where the unique cachedData is set! SearchTerm + "-cachedData"
localStorage.setItem(searchTerm + "-cachedData", JSON.stringify(cachedData));
});
}
else{
cachedData = JSON.parse(cachedData);
def.resolve(cachedData);
}
def.done(function(data) {
var resultHTML = '';
for(var i = 0; i < Object.keys(data.repositories).length; i++){
$.each(data, function(index, node){
resultHTML += '<li>'
resultHTML += '<h1>' + node[i].name + '</h1>';
resultHTML += '<p>' + node[i].owner + '</p>';
resultHTML += '</li>';
});
}
$('div#results').html(resultHTML);
});
Where would I be without StackOverflow. Thank you all!

Can't set new value for variable

I'm possibly missing something that is very obvious, but I'm not getting nowhere with this problem.
I'm simple trying to set a value of a variable after getting the value from a json feed.
I'm using jquery to get a jsonp feed and then store the value in a variable that I can use later, but its not working and the value doesn't get stored. If I console.log the value it returns it.
jQuery(document).ready(function($){
serverip = "<?php echo $_SERVER['SERVER_ADDR']; ?>";
stream_domain = "";
$.ajax({url: 'http://load.cache.is/inspired.php?ip=' + serverip, dataType:'jsonp',
success: function(data){
$.each(data, function(key, val) {
if (key == serverip){
stream_domain = val;
console.log("val: " + val);
}
});
}
});
console.log(stream_domain);
});
Here is the same code on jsfiddle.net
You are making an asynchronous request. So your code which appends the HTML execute before the success does which assigns the variable.
The code following the ajax request executes immidiatly after the request is made.
So if you require the response data then you should move your append code to be executed from the success method similar to this:
if (key == serverip){
stream_domain = val;
console.log("val: " + val);
$("<span>" + val + "</span>").appendTo(".json");
$("<span>" + stream_domain + "</span>").appendTo(".variable");
}
DEMO
The ajax call is asynchronous, so the timeline of the events is :
make ajax call
console.log
ajax call success, variable assign
Wait for the success event before using the variable. Here is your updated jsFiddle where I've added a function called in the success callback function:
function continueWorking(){
console.log(stream_domain);
$("<span>" + stream_domain + "</span>").appendTo(".variable");
}

cellUpdate from jqgrid custom formatter

I'm using jqgrid and am trying to request data from a webservice, parse it, and update a grid cell with the value. I expected to be able to do this with a custom formatter but I haven't been able to connect the dots on the asynchronous part of this function.
I've also ready that it may be wiser to use the gridLoaded { } call for this type of feature but in my mind the code I have below should work...
The formatter function gets called, make the async query which when completed fires the callback function which in turn updates the grid cell.
Any suggestions on what I may be missing would be greatly appreciated!
Thanks!
function recentPostsFormatter(cellValue, options, jsonVal) {
var encodedUrl = jsonVal.urlId;
var globalHTML = "";
var wsquery = 'webservice query goes here';
$.getJSON(wsquery, function (result) {
var html = "";
for (var i = 0; i < result.response.docs.length; i++) {
html += "<b>" + result.response.docs[i].title + "</b><br>" + result.response.docs[i].blogLink + ", " + result.response.docs[i].author + "<br>";
}
$("#blogListTable").jqGrid('setCell', object.rowId, 'recentPosts', html);
});
}

Categories

Resources