0

I am writing a short script that connects to the LastFM api to get my last scrobbled song. The issue I am having is that the JSON version has an attribute for "now playing" which when you are currently listening to a song has the value of "true". However if there is no song playing the attribute doesn't exist at all.

This is the script I currently have and when I am listening to a song via spotify or iTunes etc... it works fine.

<p>
<p class="nowplaying"> <span class="track"></span> by <span class="artist"></span></p>
<p>
<script type="text/javascript">
$.getJSON('https://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=JamesTaylor87&api_key=ADD-API-KEY-HERE&format=json', function(data) {

var artist = $(".artist"),
track = $(".track"),
np = $(".nowplaying"),
artistVal = data.recenttracks.track[0].artist["#text"],
trackVal = data.recenttracks.track[0].name,
nowplaying = data.recenttracks.track[0]["@attr"].nowplaying;

if(typeof nowplaying === "undefined"){
np.prepend("The last song I listened to was")
artist.append(artistVal);
track.append(trackVal);
} else {
np.prepend("I am currently listening to")
artist.append(artistVal);
track.append(trackVal);
}

});
</script>

However when I am not listening to anything I get the following error message (in safari) and nothing works:

undefined is not an object (evaluating 'data.recenttracks.track[0]["@attr"].nowplaying')

in chrome the error is displayed as follows:

Uncaught TypeError: Cannot read property 'nowplaying' of undefined

I have attempted to use an if statement for when it's undefined which hasn't worked and don't really know what else to try. Any help would be much appreciated.

Thoron
  • 3
  • 2
  • Have you tried debugging and seeing if 'data.recenttracks.track[0]["@attr"]' is defined or not null? It may even be the case that your @attr is misspelled or entirely wrong. – Austin Heller Oct 07 '15 at 02:03
  • Yeah, I've checked. I have looked at the JSON file as well, and the attribute just doesn't exist when a song isn't playing. I have tested the attribute when a song is playing to alert the value which returns "true". But again as soon as I stop playing a song, the attribute just returns the error "undefined is not an object". – Thoron Oct 07 '15 at 02:09
  • Yep, **nowplaying** has nothing to do with this. As @Austin said, it's related to 'data.recenttracks.track[0]["@attr"]' not existing – JSelser Oct 07 '15 at 02:11
  • apologies. Yeah when now playing doesn't exist the following is removed from the JSON file "@attr":{"nowplaying":"true"}} – Thoron Oct 07 '15 at 02:14
  • I have removed the .nowplaying section from the nowplaying = data.recenttracks.track[0]["@attr"].nowplaying; line. It alerts as "undefined" when there is no song playing and alerts as "object Object" when a song is playing. I'll just keep playing around with it. It's good practice at the end of the day. – Thoron Oct 07 '15 at 02:30

6 Answers6

2

Replace

data.recenttracks.track[0]["@attr"].nowplaying

with

data.recenttracks.track[0]["@attr"] && data.recenttracks.track[0 ["@attr"].nowplaying

That should stop the error occuring if data.recenttracks.track[0]["@attr"] is undefined

Des Horsley
  • 1,858
  • 20
  • 43
0

Try changing the line where you defined nowplaying to this:

nowplaying = (data.recenttracks.track[0]["@attr"]) ? data.recenttracks.track[0]["@attr"].nowplaying : undefined;

According to the chrome error, data.recenttracks.track[0]["@attr"] is undefined, which means you can't look for a property on it. You can use an if statement or a ternary to check whether this is defined before checking for its nowplaying property.

abiwer
  • 121
  • 3
0
var attrs = data.recenttracks.track[0]["@attr"];

if (typeof attrs !== 'undefined') {
   var nowPlaying = attrs.nowplaying;
}
Eric Lease
  • 4,114
  • 1
  • 29
  • 45
0

Try this:

var track = data.recenttracks.track[0];
var nowplaying = track.hasOwnProperty('@attr') && track['@attr'].nowplaying;
sh0rug0ru
  • 1,596
  • 9
  • 9
0

I just built a very similar function for my site with Last.fm, and ran into this same problem. I was able to solve the problem by removing subsequent .nowplaying that you've included.

See below. Hope it's helpful!

// get the api
$.getJSON('http://ws.audioscrobbler.com/2.0/?method=user.getRecentTracks&user=YOURUSERNAME&limit=1&api_key=YOURAPIKEY&format=json', function(data) {

    var latesttrack = data.recenttracks.track[0]
    var trackTitle = latesttrack.name
    var trackArtist = latesttrack.artist["#text"]

    // detect if the track has attributes associated with it
    var nowplaying = latesttrack["@attr"]

    // if nowplaying is underfined
    if (typeof nowplaying === 'undefined') {

        $('.nowplaying').html("Currently listening to nothing.")

    } else {

        $('.nowplaying p').html("Currently listening to" + trackTitle + " by " + trackArtist)

    }

});

See it in action here: http://theadamparker.com/daily

0
    <script type="text/javascript">
        //<![CDATA[
            var lastfm_api     = 'http://ws.audioscrobbler.com/2.0/';
            var lastfm_methods = 'user.getRecentTracks';
            var lastfm_user    = 'YOUR_USERNAME';
            var lastfm_key     = 'YOUR_APIKEY';
            var lastfm_limit   = '1';

            var lastfm_json    = lastfm_api + '?method=' + lastfm_methods + '&user=' + lastfm_user + '&api_key=' + lastfm_key + '&limit=' + lastfm_limit + '&format=json';

            $.getJSON(lastfm_json, function(data) {
                var html = '';
                var song   = data.recenttracks.track[0].name, 
                    artist = data.recenttracks.track[0].artist["#text"], 
                    url    = data.recenttracks.track[0].url, 
                    cover  = data.recenttracks.track[0].image[0]['#text'];

                html += '<p><a href="' + url + '" title="Click here to view song in Last.fm" target="_blank">' + song + ' by ' + artist + '<br /><br /><img src="' + cover + '" style="display: block; width: 96px; height: 96px;" /></a></p><p><a href="https://twitter.com/intent/tweet?text=Listening%20♪%20' + song + '%20by%20' + artist + '%20via%20%40Lastfm&url=' + url + '&original_referer=' + url + '" title="Click here to view song in Last.fm" target="_blank">Share on Twitter</a></p>';

                $('#recent-tracks').append(html);
            });
        //]]>
    </script>

    <div id="recent-tracks"></div>