skip to Main Content

I’m currently building a live-feed of Twitter posts. I successfully pull in new tweets using an interval of 10 seconds, the new tweets pop up immediately.

However, I am displaying the time since the tweet has been created, e.g. “24 seconds ago” or “1 day ago” and want to live-update these values as well without reloading the page. However, I do not want to use the other interval of 10 seconds, but a new interval of 1 second, to display the first second changes as well.

I created a function that updates the times properly, but that doesn’t work for new elements added by my AJAX call. To present some Code:

HTML doesn’t really matter, the important part is the span with the class “time-difference”, which holds the “2 seconds” or “3 days” and should be changed dynamically.

<div class="row tweet-wrapper" data-crdate="' . $tw_timestamp . '">
<div class="col-xs-1 user-profile-picture">
    <img class="img-responsive" src="' . $user_profile_pic . '">
</div>
<div class="col-xs-11 tweet-content">
    <p class="tweet-header">
        <a href="https://twitter.com/' . $user_screen_name . '">' . $user_screen_name . '</a>

        <span class="tweet-header-sub">' . $user_name . '</span>
    </p>
    <p class="tweet-content">
        ' . $tw_text . '
    </p>
    ' . (!empty($images) ? '
    <p>
        ' . $images . '
    </p>
    ' : '') . '
    <p class="tweet-footer">
        <span class="tweet-footer-time">
            <a href="https://twitter.com/' . $tw_gen_screen . '/statuses/' . $tw_gen_tw_id . '">
                <img height="15" width="15" src="res/img/twitter-logo.svg"> 
                <span class="time-difference">' . $difference_show . ' ' . $difference_word . '</span> ago
            </a>
        </span>
    </p>
</div>
</div>

JQuery – AJAX-Call – $(‘.container-fluid’).prepend(data); adds the new container to my wrapper div

function loadNewTweets() {
var latestTweet = $('div.tweet-wrapper:first').data('crdate');

$.get('res/php/update.php', { latest: latestTweet }, function(data) {
    if(data && data != '') {
        $('.container-fluid').prepend(data);

        window.scrollTo(0, 0);
    }
}, 'html');
};

Alongside with the interval calling the function, outside of any $(function(){}) calls.

var intervalLoadTweets = setInterval(function() {
    loadNewTweets();        
}, 1000 * loadNewTweetsInterval);

Update.php (serving ajax)
Basically does a bunch of stuff to format tweets, filters out already existing tweets by comparing their timestamps and then returns a div container that’s exactly the same as above.

I can’t setup a fiddle as I don’t want to reveal my production twitter api secrets, but I think it should be understandable without.

I’ve seen different answers to similar questions (renewing interval, redeclaring function, …) but none of those seemed to work for me, as the time of existing (on page load) tweets is updated in live time, but newly added tweets through Ajax aren’t changing at all.

I built a Codepen that does nearly the same thing, adding content but without AJAX, which works: https://codepen.io/anon/pen/PKVmbg

So apparently, ajax is causing the trouble for me, but I have no idea how to fix this.

Edit:
Function changing the time values:

var reloadTweetTimes = function() {
$.each(findElement, function() {
    var crdate      = $(this).data('crdate');
    var nowts       = parseInt($.now() / 1000);
    var difference  = nowts - crdate;

    var difference_word = '';
    var difference_show = '';

    if(difference == 1) {
        difference_word = 'second';
        difference_show = difference;
    } 
    else if(difference < 60) {
        difference_word = 'seconds';
        difference_show = difference;
    } 
    else if(difference >= 60 && difference < (60 * 2)) {
        difference_word = 'minute';
        difference_show = parseInt((difference / 60));
    }
    else if(difference < (60 * 60)) {
        difference_word = 'minutes';
        difference_show = parseInt((difference / 60));
    }
    else if(difference >= (60 * 60) && difference < (60 * 60 * 2)) {
        difference_word = 'hour';
        difference_show = parseInt((difference / 60 / 60));
    }
    else if(difference < (60 * 60 * 24)) {
        difference_word = 'hours';
        difference_show = parseInt((difference / 60 / 60));
    }
    else if(difference >= (60 * 60 * 24) && difference < (60 * 60 * 24 * 2)) {
        difference_word = 'day';
        difference_show = parseInt((difference / 60 / 60 / 24));
    }
    else {
        difference_word = 'days';
        difference_show = parseInt((difference / 60 / 60 / 24));
    }

    $(this).find('.time-difference').text(difference_show + ' ' + difference_word);

    $('.tweet-wrapper').css('opacity', 1);
});
};

Interval calling the function

var intervalRefreshTimes = setInterval(function() {
    reloadTweetTimes();
}, 1000 * refreshTimesInterval);

2

Answers


  1. Add the updating time difference code in the success method of the ajax call. As the DOM will not be available if you are updating after the ajax call,, since $.get() will create a new thread.

    $.get('res/php/update.php', { latest: latestTweet }, function(data) {
    if(data && data != '') {
        $('.container-fluid').prepend(data);
        // Add here the time difference calculation function.
        window.scrollTo(0, 0);
    }
    }, 'html');
    };
    
    Login or Signup to reply.
  2. I’m still a little unclear on exactly what elements reloadTweetTimes is iterating over, because you don’t have a definition for findElement. But I suspect the problem is that findElement is jQuery object bound only to the elements that were present when the document loads. If that’s true, you have two options:

    1. Add new elements to findElement after you load them with ajax and
      add them the document.
    2. Search for new items every time reloadTweetTimes runs. (could get slow if the page loads too many elements)

    If you want to add how findElement is set, I can provide code samples for both.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search