Jammming part 2: dynamically calculate the playlist total time

Hello everyone,

I have completed the two versions of the project (with function components and with classes components), and now I want to add a new feature: calculate the playlist total time dynamically.

For this, I have:

  • fetched the duration_ms in Spotify.js
  • displayed the duration of the song in minutes (defined in TrackList.js)

Now I have added a new feature in the App.js as useState : totalTime and setTotalTime, by default on ‘0:0’.

I passed the props from App.js down to Playlist.js and then to my new function Component Time.js

In this Time.js, I am rendering a HTML element where I display the total time (props.totalTime), and define a function which should update the state totalTime each time the playlistTracks state is changed, using the useCallback from ‘react’.

Problem: nothing happens !

When I try to debug with Visual Code Studio, adding breakpoints, I am told that the function is not defined, even if no error is shown in devTools of Chrome.

Have anyone ideas where the problem could be ?

Here are my files:

App.js

import React, { useState, useCallback, useEffect } from "react"; import "./App.css"; import Playlist from "../Playlist/Playlist"; import SearchBar from "../SearchBar/SearchBar"; import SearchResults from "../SearchResults/SearchResults"; import Spotify from "../../util/Spotify"; const App = () => { const [searchResults, setSearchResults] = useState([]); const [playlistName, setPlaylistName] = useState("New Playlist"); const [playlistTracks, setPlaylistTracks] = useState([]); const [totalTime, setTotalTime] = useState('0:0'); const search = useCallback((term) => { Spotify.search(term).then(setSearchResults); }, []); const addTrack = useCallback( (track) => { if (playlistTracks.some((savedTrack) => savedTrack.id === track.id)) return; setPlaylistTracks((prevTracks) => [...prevTracks, track]); }, [playlistTracks] ); const removeTrack = useCallback((track) => { setPlaylistTracks((prevTracks) => prevTracks.filter((currentTrack) => currentTrack.id !== track.id) ); }, []); const updatePlaylistName = useCallback((name) => { setPlaylistName(name); }, []); const savePlaylist = useCallback(() => { const trackUris = playlistTracks.map((track) => track.uri); Spotify.savePlaylist(playlistName, trackUris).then(() => { setPlaylistName("New Playlist"); setPlaylistTracks([]); }); }, [playlistName, playlistTracks]); return ( <div> <h1> Ja<span className="highlight">mmm</span>ing </h1> <div className="App"> <SearchBar onSearch={search} /> <div className="App-playlist"> <SearchResults searchResults={searchResults} onAdd={addTrack} /> <Playlist playlistName={playlistName} playlistTracks={playlistTracks} onNameChange={updatePlaylistName} onRemove={removeTrack} onSave={savePlaylist} totalTime={totalTime} handleTime = {setTotalTime} /> </div> </div> </div> ); }; export default App;

PlayList.js:

import React, { useCallback, useEffect } from "react"; import "./Playlist.css"; import TrackList from "../TrackList/TrackList"; import Time from "../Time/Time"; const Playlist = (props) => { const handleNameChange = useCallback( (event) => { props.onNameChange(event.target.value); }, [props.onNameChange] ); return ( <div className="Playlist"> <input onChange={handleNameChange} defaultValue={"New Playlist"} /> <TrackList tracks={props.playlistTracks} isRemoval={true} onRemove={props.onRemove} /> <br/> <Time handleTime={props.handleTime} totalTime={props.totalTime} /> <button className="Playlist-save" onClick={props.onSave}> SAVE TO SPOTIFY </button> </div> ); }; export default Playlist;

Time.js

import React, {useCallback} from "react"; const Time =(props) => { const handleTotalTime = useCallback(()=> { let totalTime = 0; props.playlistTracks.forEach((track)=> { totalTime += track.duration_ms; }) const minutes = Math.floor(totalTime/60000); const seconds = ((totalTime % 60000) /1000).toFixed(0); let newTime = minutes + ':' + (seconds < 10 ? '0': '') + seconds; props.setTotalTime(newTime); }, [props.playlistTracks]); return ( <span>Your Playlist Total Time is currently: <input value={props.totalTime} onChange={handleTotalTime} /></span> ); } export default Time;

Did I messed up with the props ?

Thank you very much in advance !

Which function is it saying is not defined? Can you copy/paste the error?

Hello @taylorsabbag,

thank you for your answer !

Here is the screenshot : I tried to add several breakpoints to see how the code reacts (huhu), but I am stull not used to it.

Thank you in advance,

Marie