I am trying to get all objects that are in a json string via $.getJSON
and it works but I am having trouble showing them all (it only is showing the last object). I know its because its overwriting each entry via .$each
but I've no clue on how to fix this, as I tried to append it but that just kept displaying each of the entries multiple times (I have it set to update every 5 seconds, to see if there are more entries available). Anyway, here is the code I have in place (both jQuery and PHP)
jQuery Code -
$(function() {
function buildOnlineFriendList() {
$.getJSON("/members/friends/get-friends-online")
.done(function(msg) {
if (jQuery.isEmptyObject(msg)) {
$('#friends-online').html("No friends are online.");
} else {
$.each(msg, function(key, value) {
// how to display each friend online without overwriting each one to only display the last. :/
$('#friends-online').html("<a href=\"/members/chat/" + value.id + "\" class=\"chat-with\">" + value.name + "</a><br>");
});
}
}).fail(function(msg) {
$('#friends-online').html(msg.message);
});
}
setInterval(function() {
buildOnlineFriendList();
}, 5000);
buildOnlineFriendList();
});
PHP code -
public function getFriendsOnline()
{
$query = $this->connection->execute("SELECT members.username AS friend_username, friends_online.user_id AS fo_id FROM friends_online, friends, members
WHERE friends_online.user_id = friends.friend_id AND members.id = friends.friend_id AND friends.user_id = " . $this->getUserId()['id']);
if ($query->count() > 0) {
// get the id/username of the friend(s) online
foreach ($query as $values) {
$friends_online[] = array('id' => $values['fo_id'], 'name' => $values['friend_username']);
}
return $friends_online;
} else {
throw new FriendsException("No friends are online.");
}
}
Any help would be appreciated.
Thanks!
(I can try and provide more information if my question is unclear)
You already know it's overwriting the values when writing using $.each
. The issue is it's writing the HTML for the friends-online
element each loop. All you need to do is to set this value in a variable and update the variable in each iteration. Then after the loop is done, set the HTML for the element. I've modified your function to:
function buildOnlineFriendList() {
$.getJSON("/members/friends/get-friends-online")
.done(function(msg) {
// create a variable to hold the html string
var html = "";
if (jQuery.isEmptyObject(msg)) {
$('#friends-online').html("No friends are online.");
} else {
$.each(msg, function(key, value) {
// set the value of the html here
html += "<a href=\"/members/chat/" + value.id + "\" class=\"chat-with\">" + value.name + "</a><br>";
});
// set the html here, after the loop.
$('#friends-online').html(html);
}
}).fail(function(msg) {
$('#friends-online').html(msg.message);
});
}
Try replacing $('#friends-online').html(...
with $('#friends-online').append(...
. At the moment this line is resetting the HTML of #friends-online over and over, whereas using append will add each new user to the element.
You will need to also add $('#friends-online').empty()
as the first line of your timer, i.e.
setInterval(function() {
$('#friends-online').empty();
buildOnlineFriendList();
}, 5000);
Or in the function itself, i.e.
function buildOnlineFriendList() {
$('#friends-online').empty();
$.getJSON("/members/friends/get-friends-online") ...
Try replace this:
$('#friends-online').html("<a href=\"/members/chat/" + value.id + "\" class=\"chat-with\">" + value.name + "</a><br>");
With this:
$('#friends-online').append("<a href=\"/members/chat/" + value.id + "\" class=\"chat-with\">" + value.name + "</a><br>");
The .html() method will overwrite all existing HTML within the selected element. The .append() method will add the content on to the end of the existing HTML
$("#friends-online")
.append(
$("<a>")
.attr("href", "/members/chat/" + value.id)
.attr("class", "chat-with")
)
.append($("<br>"));