You could use a scheduled job to hit the API every three minutes and cache the results. When you get to get results you could also broadcast an event that informs your front end through websockets that the songs have changed.
API Refresh automatically and Website speed slow.
Hello everyone, I'd like to quickly explain the situation. Essentially, I've created a Livewire component that allows me to fetch data from a radio API to get songs. These songs change every 3 minutes, and I want to update my Blade view whenever the properties of this API change.
class TitleSong extends Component
{
public $songTitle;
public $songArtist;
public $songImage;
public $secondsTotal;
public $secondsElapsed;
public $elementToShow;
public $remainingTime;
public function render()
{
return view('livewire.title-song');
}
public function boot()
{
$this->fetchSongData();
}
public function fetchSongData()
{
try{
$response = Http::get('MY API');
$data = $response->json();
$this->songArtist = $data['song']['artist'];
$this->secondsElapsed = $data['song']['seconds_elapsed'];
$this->secondsTotal = $data['song']['seconds_total'];
$this->songImage = $data['song']['art'];
$this->songTitle = $data['song']['title'];
$remainingTime = $this->secondsTotal - $this->secondsElapsed;
$this->remainingTime = $remainingTime;
} catch (\Throwable $th) {
dd($th->getMessage());
}
}
}
And since this elements needs to be splitted in the whole document I made it possible with a new variable of "$elementToShow" This is the view:
<div wire:poll.{{$remainingTime}}="fetchSongData">
@if ($elementToShow === 'songTitle')
<h1 id="songTitle" style="color: var(--quaternary-color); font-weight: 600" class="text-4xl">{{$songTitle}}</h1>
@elseif ($elementToShow === 'songArtist')
<p id="songArtist" class="mt-2 ml-1" style="color: var(--quinary-color); font-weight: 400; font-size: 15px">{{$songArtist}}</p>
@elseif ($elementToShow === 'secondsElapsed')
<span id="secondsElapsed" class="current-time">0:00</span>
@elseif ($elementToShow === 'secondsTotal')
<span id="secondsTotal" class="total-time"> {{substr($secondsTotal, 0, 1) . ':' . substr($secondsTotal, 1, 2)}}</span>
@elseif($elementToShow === 'songImage')
<img style="position: absolute; left: 12%; top: 2%; border-radius:20px; z-index: 1" width="220px" height="200px" src="{{$songImage}}" />
@endif
</div>
Now I would ask you if there's a better way to do this without using wire:poll or something else. Unfortunately this is causing me A LOT OF PAIN, because it affects so much the speed of my website. The website right now takes 5 seconds to load the HTML document.
Please or to participate in this conversation.