0

I have a site that grabs data from the last.fm API. I would like it to auto-refresh every 5 seconds without me manually refreshing my page. Here's what I've tried:

const api_url = "https://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=flarely&api_key=key_here&format=json&limit=1"; 

// making an async function (non-async function won't work -_-)
async function get_data_from_api(url) { 
    
    //Data
    const response = await fetch(url); 
    var data = await response.json();
    //Song info
    var track = data["recenttracks"]["track"][0]["name"]
    var artist = data["recenttracks"]["track"][0]["artist"]["#text"]
    document.getElementById('music').innerHTML = "🎧 listening to " + track +  " by " + artist;
}

setInterval(get_data_from_api, 1000);
    
 //Calling the function, 
 get_data_from_api(api_url); 

What can I do to auto-refresh it every 10 seconds?

Kaviranga
  • 576
  • 2
  • 10
  • 24
geneva
  • 27
  • 2
  • 5

2 Answers2

1

Maybe you could make the get_data_from_api function call itself after fetching the data. Use setTimeout to make it wait a while before making a new request. You could improve this code with error handling and make something like try again immediately in case of fetch error.

const api_url = "https://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=flarely&api_key=key_here&format=json&limit=1"; 

async function get_data_from_api(api_url) { 
    // data
    const response = await fetch(api_url); 
    var data = await response.json();
    // song info
    var track = data["recenttracks"]["track"][0]["name"]
    var artist = data["recenttracks"]["track"][0]["artist"]["#text"]
    document.getElementById('music').innerHTML = "🎧 listening to " + track +  " by " + artist;
    setTimeout(() => get_data_from_api(api_url), 10000)
})

get_data_from_api(api_url)

With this approach it will update 10 seconds after last update. Using SetInterval will call the update function every 10 seconds, so if the function takes 6 seconds to complete the request it will be really updating every 4 seconds, and if some request takes more than 10 seconds there will be some simultaneous updates. All in all I think this self calling function is a better approach.

Alvaro Flaño Larrondo
  • 5,516
  • 2
  • 27
  • 46
1

Firstly, your code needs some cleanup:

  1. You are missing the ending ; (semi-colon) in the following two lines:
var track = data["recenttracks"]["track"][0]["name"]
var artist = data["recenttracks"]["track"][0]["artist"]["#text"]
  1. Your get_data_from_api function doesn't need any arguments, as you already have api_url constant declared for the link to fetch the data

  2. You do not refer to the api_url from anywhere inside the get_data_from_api function.

The Timing Tutorial at W3Schools has a very simple demo and I combined your code with theirs to demonstrate how it worked for me (except I don't have any API for last.fm so my data didn't show up, but the code ran):

<!DOCTYPE html>
<html>
<body>

<p>A script on this page starts this clock:</p>

<p id="demo">Current Time</p>
<p id="demo2">Fetch Data</p>
<p id="last">Fetch Time</p>

<script>

const api_url = "https://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=flarely&api_key=key_here&format=json&limit=1";

var myVar = setInterval(myTimer, 1000);
var myVar2 = setInterval(get_data_from_api, 10000);

function myTimer() {
    var d = new Date();
    document.getElementById("demo").innerHTML = "Current Time: " + d.toLocaleTimeString();
}

// making an async function (non-async function won't work -_-)
async function get_data_from_api() {
    // data
    var d2 = new Date();
    document.getElementById("last").innerHTML = "Fetch Time: " + d2.toLocaleTimeString();
    const response = await fetch(api_url);
    var data = await response.json();
    // song info
    var track = data["recenttracks"]["track"][0]["name"];
    var artist = data["recenttracks"]["track"][0]["artist"]["#text"];
    document.getElementById("demo2").innerText = "Fetched Data " . response;
}

myTimer();
get_data_from_api();

</script>

</body>
</html>

I added the 2nd timer to demonstratae that the code inside the funciton is indeed running.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Nyamul
  • 76
  • 4