I am building a playlist player widget for my app using Soundcloud API. I am able to fetch the data but I am running into a design/technical issue when I need to implement the play/pause feature for a given track.
The GET
method returns a JSON track (song) with multiple functions associated, such as response.play()
, response.pause()
, etc. Currently, my onClick()
handle for pausing and playing the song fetches new data for the same track and overrides the current song, which is not what I want. I want to be able to play the song, the pause/play it without restarting.
[-------- Working JSFiddle here !!---------]
const SC = require('soundcloud');
SC.initialize({
client_id: '1dff55bf515582dc759594dac5ba46e9'
});
const playIcon = 'https://www.pngfind.com/pngs/m/20-201074_play-button-png-image-background-circle-transparent-png.png';
const pauseIcon = 'https://thumbs.dreamstime.com/z/pause-button-icon-transparent-background-sign-flat-style-204042531.jpg';
async function getJson(trackId) {
let response = await SC.stream('/tracks/' + trackId);
return response;
}
const Playlist = () => {
const[playState, setPlayState] = React.useState(false);
const handlePlayClick = () => {
getJson(913128502).then((track) => {
track.setVolume(0.025); //increase if you don't hear background sound
playState ? track.pause() : track.play();
setPlayState(!playState);
});
}
return (
<img src={!playState ? playIcon : pauseIcon }
onClick={() => { handlePlayClick() } }
height="100" width="100" >
</img>
)
}
export default Playlist;
I have looked at several SOs posts trying to understand how to store fetched data in a global variable. From my understanding, this can't quite be done because of synchronicity, I can only use the track
GET response and its associated functions only inside the function
getJson(trackId).then((track) => {
// can only call track.play() or track.pause() locally here ?
});
To bypass this, I tried to do
let globalTrack;
getJson(trackId).then((track) => {
globalTrack = track;
});
globalTrack.play() // undefined error
I have further tried to use other tools like async
/await
but with no success.
I am at a loss for ideas and lost enough hair over this issue. Does anyone know how I can achieve what I want?
You can use useEffect() hook to get a track, it will fetch the track once when the component is first mounted.
https://jsfiddle.net/x7j0qwvh/20/
const [track, setTrack] = React.useState(null);
React.useEffect(() => {
musicFetch(913128502).then((music) => {
music.setVolume(0.025);
setTrack(music);
});
}, [])