0

I am working on a WebApp to play music that I parse from twitter while I am work. currently I am storing the songs by song Id that I get from SoundCloud. But I am not able to organize it to play the last song played. I looked at changing how I have the key in my database to the date but then I would have to check if the song already exists and I think that would be harder to do. But I would like to figure out how to compare the date and then display the most recent song.

My data looks like this:

"6655480" : {
      "Date" : "12/16/2014 2:58:39 am",
      "SongName" : "The Island (Steve Angello, An21 & Max Vangeli remix)",
      "Tweet" : "Pendulum/Steve Angello/An21/Vangeli - The Island playing on #BPM - @sxmElectro",
      "uri" : "https://api.soundcloud.com/tracks/6655480"
    }

I tried this:

$scope.Song.sort(function(a,b){
var c = new Date(a.Date);
var d = new Date(b.Date);
return c-d;
});

But it is not working. Any help is appreciated.

I get $scope.Song like this:

var ref = new Firebase("https://app.firebaseio.com/SC");
var sync = $firebase(ref);
$scope.Song = sync.$asArray();

UPDATE:

So I have tried to solve this by doing:

    $scope.log = [];
    angular.forEach(values, function(value, key) {
      value.sort(function(a,b){
            var c = new Date(a.Date);
            var d = new Date(b.Date);
            return c-d;
      }
    }, log);

But now nothing works. What is the issue with my syntax? is this the proper way to do this?

FPcond
  • 581
  • 2
  • 7
  • 21
  • your structure is more complex than your simplified `sort`. What does `Song` look like? – charlietfl Dec 24 '14 at 18:34
  • updated my answer I can give you more code if needed – FPcond Dec 24 '14 at 18:55
  • don't care really how you get it, what does the full structure look like? You can't do `a.Date` needs to be something like: `a.6655480.Date` but the ID keys will all be different. Much simpler without those ID objects – charlietfl Dec 24 '14 at 18:59
  • So to access the date I just use an ng-repeat so could I use a forEach function to iterate through the array and pull the date and then compare the date and push the object into a new arra? – FPcond Dec 24 '14 at 19:13
  • sure, that would be simple enough – charlietfl Dec 24 '14 at 19:17
  • use console to log what's inside your forEach. It's probably not array's to sort but that depends on full structure of FB data – charlietfl Dec 25 '14 at 00:43
  • Just confirming what format is the `date` field in Firebase? I know you converted it to a Date object but if it's stored as a string, you might need to convert it back. I don't think this is the issue but thought I'd ask. – aug Dec 25 '14 at 01:27
  • @aug so the Date is just like it is above and is stored as a string. – FPcond Dec 25 '14 at 04:05
  • O NO! an anonymous down vote and on Christmas eve! – FPcond Dec 25 '14 at 04:06
  • Yup, some insane downvoter is roaming SO even today... – Shomz Dec 25 '14 at 04:14

1 Answers1

0

The Simple Fetch Way

If you only need to fetch the newest song without any sorting and filtering, you can simply loop the object and select the most recent one:

var songs = {
  "6655480": {
    "Date": "12/16/2014 2:58:39 am",
    "SongName": "The Island (Steve Angello, An21 & Max Vangeli remix)",
    "Tweet": "Pendulum/Steve Angello/An21/Vangeli - The Island playing on #BPM - @sxmElectro",
    "uri": "https://api.soundcloud.com/tracks/6655480"
  },
  "234": {
    "Date": "12/13/2014 2:58:39 am",
    "SongName": "Some Older Song",
    "Tweet": "Pendulum/Steve Angello/An21/Vangeli - The Island playing on #BPM - @sxmElectro",
    "uri": "https://api.soundcloud.com/tracks/6655480"
  },
  "123": {
    "Date": "12/19/2014 2:58:39 am",
    "SongName": "Some Newer Song",
    "Tweet": "Pendulum/Steve Angello/An21/Vangeli - The Island playing on #BPM - @sxmElectro",
    "uri": "https://api.soundcloud.com/tracks/6655480"
  },
  "253252": {
    "Date": "12/24/2014 2:58:39 am",
    "SongName": "The Newest Song",
    "Tweet": "Pendulum/Steve Angello/An21/Vangeli - The Island playing on #BPM - @sxmElectro",
    "uri": "https://api.soundcloud.com/tracks/6655480"
  }
}

var newestDate = new Date(0); // Jan 01 1970 
var newestSong;
for (var i in songs) {
  if (new Date(songs[i].Date) > newestDate) {
    newestDate = new Date(songs[i].Date)
    newestSong = songs[i];
  }
}

alert('The newest song is: ' + newestSong.SongName);

The ng-repeat Filter Way

The simplest Angular way to do it would be to use ng-repeat with the orderBy filter with the reverse argument:

ng-repeat="song in Song | orderBy:'Date':true"

See here: https://docs.angularjs.org/api/ng/filter/orderBy

Note: since the orderBy filter only works with arrays (and you can't simply sort an object anyway), I had to add a custom filter in between to convert the object to an array (used the one from https://stackoverflow.com/a/19387871/965907), so we have this:

ng-repeat="song in Song | objToArrayCustomFilter | orderBy:'Date':true"

See it in action here (added a simple toggle button to flip the reverse flag):

angular.module('test', [])
  .filter('object2Array', function() {
    return function(input) {
      var out = [];
      for (var i in input) {
        out.push(input[i]);
      }
      return out;
    }
  })
  .controller('Ctrl', function($scope) {
    $scope.reverse = true;
    $scope.songs = {
      "6655480": {
        "Date": "12/16/2014 2:58:39 am",
        "SongName": "The Island (Steve Angello, An21 & Max Vangeli remix)",
        "Tweet": "Pendulum/Steve Angello/An21/Vangeli - The Island playing on #BPM - @sxmElectro",
        "uri": "https://api.soundcloud.com/tracks/6655480"
      },
      "234": {
        "Date": "12/13/2014 2:58:39 am",
        "SongName": "Some Older Song",
        "Tweet": "Pendulum/Steve Angello/An21/Vangeli - The Island playing on #BPM - @sxmElectro",
        "uri": "https://api.soundcloud.com/tracks/6655480"
      },
      "123": {
        "Date": "12/19/2014 2:58:39 am",
        "SongName": "Some Newer Song",
        "Tweet": "Pendulum/Steve Angello/An21/Vangeli - The Island playing on #BPM - @sxmElectro",
        "uri": "https://api.soundcloud.com/tracks/6655480"
      },
      "253252": {
        "Date": "12/24/2014 2:58:39 am",
        "SongName": "The Newest Song",
        "Tweet": "Pendulum/Steve Angello/An21/Vangeli - The Island playing on #BPM - @sxmElectro",
        "uri": "https://api.soundcloud.com/tracks/6655480"
      }
    }

  })
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="test" ng-controller="Ctrl">
  <p ng-repeat="song in songs | object2Array | orderBy:'Date':reverse"><strong>{{song.SongName}}</strong>: {{song.Date}}</p>
  <button ng-click="reverse = !reverse">Toggle order</button>
</div>

On Plunker: http://plnkr.co/edit/r8oDr5PtsPVZGO5WFaWR?p=preview

Community
  • 1
  • 1
Shomz
  • 37,421
  • 4
  • 57
  • 85
  • The ng-repeat isnt the solution I was looking for but I am tracking on what you mean. I currently DISPLAY my songs in date order by doing
  • Song Name: {{s.SongName}}
  • – FPcond Dec 25 '14 at 04:10
  • I am liking your other solution I am testing it now – FPcond Dec 25 '14 at 04:11
  • Yeah, if you just need to fetch the latest, no need to complicate things. – Shomz Dec 25 '14 at 04:14