PATH Realtime Arraival

HTML

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <meta content="width=device-width,initial-scale=1,minimal-ui" name="viewport">
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700,400italic|Material+Icons">
    <link rel="stylesheet" href="https://unpkg.com/vue-material@beta/dist/vue-material.min.css">
    <link rel="stylesheet" href="https://unpkg.com/vue-material@beta/dist/theme/default.css">
  </head>
  <body>
    <div id="app">
      <md-toolbar :md-elevation="1">
        <span class="md-title">Realtime PATH Arrival Times</span>
        <md-subheader>by&nbsp;<a href="https://razza.dev" target="_blank">Matt Razza</a>&nbsp;| Data quality is not guaranteed. This is not affiliated with PATH or PANYNJ.</md-subheader>
      </md-toolbar>
      <md-list class="md-double-line" v-for="station in stations">
        <md-subheader>{{ station.name }}</md-subheader>

        <md-divider></md-divider>

        <md-list-item v-for="train in station.trains">
          <md-icon class="md-primary">train</md-icon>

          <div class="md-list-item-text">
            <span>{{ train.name }}</span>
          </div>

          <div class="md-list-action">
            <span>{{ train.arrival_time }}</span>
          </div>
        </md-list-item>
      </md-list>
    </div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue-resource@1.5.1"></script>
    <script src="https://unpkg.com/vue-material@beta"></script>
    <script src="https://momentjs.com/downloads/moment.min.js"></script>
  </body>
</html>

CSS

.md-list.md-double-line {
  width: 520px;
  max-width: 100%;
  display: inline-block;
  vertical-align: top;
  border: 1px solid rgba(0, 0, 0, 0.12);
  margin: 2px;
}

JavaScript

Vue.use(VueMaterial.default);

new Vue({
  el: '#app',
  data: {
    timer: '',
    stations: {
      "newark": {
        name: "Newark Penn",
        trains: []
      },
      "harrison": {
        name: "Harrison",
        trains: []
      },
      "journal_square": {
        name: "Journal Square",
        trains: []
      },
      "grove_street": {
        name: "Grove Street",
        trains: []
      },
      "exchange_place": {
        name: "Exchange Place",
        trains: []
      },
      "world_trade_center": {
        name: "World Trace Center",
        trains: []
      },
      "newport": {
        name: "Newport",
        trains: []
      },
      "hoboken": {
        name: "Hoboken",
        trains: []
      },
      "christopher_street": {
        name: "Christopher Street",
        trains: []
      },
      "ninth_street": {
        name: "9th Street",
        trains: []
      },
      "fourteenth_street": {
        name: "14th Street",
        trains: []
      },
      "twenty_third_street": {
        name: "23rd Street",
        trains: []
      },
      "thirty_third_street": {
        name: "33rd Street",
        trains: []
      }
    }
  },
  created: function() {
    this.fetchStations();
    this.timer = setInterval(this.fetchStations, 5000)
  },
  methods: {
    fetchStations: function() {
      for (var curr_station in this.stations) {
        this.$http.get("https://path.api.razza.dev/v1/stations/" + curr_station + "/realtime").then((function(station) {
          return function(result) {
            this.stations[station].trains = result.body.upcomingTrains.sort(function(a, b) {
              return Date.parse(a.projectedArrival) - Date.parse(b.projectedArrival);
            }).map(function(train) {
              return {
                name: train.lineName,
                arrival_time: moment(Date.parse(train.projectedArrival)).fromNow()
              };
            });
          }
        })(curr_station));
      }
    }
  },
 ...