0

I have been working this morning on creating a web app that takes information from a JSON file - in this case, tweet information from the @POTUS account, as The White House just made a ton of information publically accessible - and presents it on the screen.

Specifically, I have been working on taking the JSON file of @POTUS tweet information, and displaying the text of the tweet, and the date. The date is taken from a timestamp, and I have used a bit of JS to translate it into a format that is appealing to me.

My problem is this: the date shows up correctly in Chrome (where I have been testing), but when viewing it in Safari, Firefox, or a mobile device, the date returns "undefined NaN, NaN", where month is returning "undefined" and day and year are both returning "NaN". Looking through my code, I cannot find a reason why this would be happening.

Here is my HTML file in it's entirety:

<!DOCTYPE html>
<html>
   <head>
      <meta charset="utf-8">
      <title>@POTUS</title>
      <link rel="stylesheet" href="assets/css/main.css">
      <link href="https://fonts.googleapis.com/css?family=Lato:300,900" rel="stylesheet">
   </head>
   <body>
      <div class="tweet-container">
         <header>
            <h1 class="title">
               <a class="twitter" href="http://www.twitter.com/potus" target="_blank">@POTUS</a> Tweets
            </h1>
            <p class="description">A complete archieve of tweets from President Barack Obama, presented in reverse chronological order.</p>
         </header>
         <div id="potus-tweets"></div>
         <button id="btn">New Tweet</button>
      </div>
      <script src="assets/js/tweets.js"></script>
   </body>
</html>

Here is my JS file in it's entirety:

var tweetCounter = 0;
var tweetsContainer = document.getElementById("potus-tweets");
var btn = document.getElementById("btn");

btn.addEventListener("click", function(){
  var request = new XMLHttpRequest();
  request.open('GET', 'assets/js/potus.json');
  request.onload = function(){
    var potusTweets = JSON.parse(request.responseText);
    loadTweets(potusTweets);
  };
  request.send();
});

function loadTweets(data){

  var monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
  var date = new Date(data[tweetCounter].timestamp);
  var year = date.getFullYear();
  var month = date.getMonth();
  var day = date.getDate();

  var tweet = "";

  for (i = 0; i < 1; i++){
    tweet += '<div class="tweet"><p class="copy">' + data[tweetCounter].text + '</p><p class="date">' + monthNames[month] + ' ' + day + ', ' + year + '</p></div>';
    tweetCounter++;
  };

  tweetsContainer.insertAdjacentHTML('beforeend', tweet);
};

For reference, the project is live here: http://thejessicafelts.github.io/projects/POTUS-Tweets/

And the code can be found here: https://github.com/thejessicafelts/POTUS-Tweets

Any insights as to why this isn't working would be extremely appreciated. I have been trying to troubleshoot this all morning, and I cannot see anything that would be causing the return of "undefined NaN, NaN".

Thanks in advance

Jessica
  • 1
  • 3
  • is this the link you're making a GET request to ?https://github.com/thejessicafelts/POTUS-Tweets/assets/js/potus.json I need it to debug this code on both browsers (if yes, then I am getting an {error: not found}) – Amresh Venugopal Jan 15 '17 at 17:08
  • Nevermind, I got the link. – Amresh Venugopal Jan 15 '17 at 17:11
  • Probably a duplicate of [*Why does Date.parse give incorrect results?*](http://stackoverflow.com/questions/2587345/why-does-date-parse-give-incorrect-results). – RobG Jan 15 '17 at 20:37

2 Answers2

1

Firstly, a sample of the timestamp as it was an important piece of input which is missing in the question.

{ // A sample tweet in your array.
  "tweet_id": 796018814072672300,
  "in_reply_to_status_id": "",
  "in_reply_to_user_id": "",
  "timestamp": "2016-11-08 15:57:29 +0000",
  "source": "<a href=\"http://twitter.com\" rel=\"nofollow\">Twitter Web Client</a>",
  "text": "Today, progress is on the ballot. Go vote - then make sure your friends, your family, and everyone you know votes too.",
  "retweeted_status_id": "",
  "retweeted_status_user_id": "",
  "retweeted_status_timestamp": "",
  "expanded_urls": ""
}

With that put up for reference I would link to the MDN doc for the Date constructor.

//Syntax:
new Date(); [1]
new Date(value); [2]
new Date(dateString); [3]
new Date(year, month[, date[, hours[, minutes[, seconds[, milliseconds]]]]]); [4]

From the object I picked up from your json asset, and then following this description, you are using the third syntax. I'll quote from the documentation that the dateString argument must comply with the date.parse method

dateString

String value representing a date. The string should be in a format recognized by the Date.parse() method (IETF-compliant RFC 2822 timestamps and also a version of ISO8601).

Coming closer to the cause of your problem, I'll mention the documentation for date.parse

dateString

A string representing an RFC2822 or ISO 8601 date (other formats may be used, but results may be unexpected).

Yes, unexpected. Further down in the description you may find:-

Because of the variances in parsing of date strings, it is recommended to always manually parse strings as results are inconsistent, especially across different ECMAScript implementations where strings like "2015-10-12 12:00:00" may be parsed to as NaN, UTC or local timezone.

Now that sounds familiar.

I tested the same string without the timezone offset on firefox 47.0.2

var a = new Date("2016-11-08 15:57:29")
a.getDate()
// returns 8
a.getMonth()
//returns 10
a.getFullYear()
//returns 2016
Community
  • 1
  • 1
Amresh Venugopal
  • 9,299
  • 5
  • 38
  • 52
  • `new Date("2016-11-08 15:57:29")` returns NaN in Safari. Don't parse strings with the Date constructor (it's equivalent to Date.parse for parsing), use a small function or library. – RobG Jan 15 '17 at 20:35
  • I understand. I was just giving a test situation where it works in firefox. I do have it included in my answer that the datestring approach can have unexpected results. – Amresh Venugopal Jan 16 '17 at 03:16
0

Convert your timestamp to milliseconds, then feed them the Date() constructor:

var a = Date(<date in milliseconds>);

Thevs
  • 3,189
  • 2
  • 20
  • 32