Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Typescript error : "audioPlayer.current may be null"

I’m trying to learn Typescript and for that I came back on some components to convert them into an errorless Typescript file.

I have here a bunch of errors that can’t find the cause.I trying different options, but can’t figure it out.

The first one is on refs. When I use theme with ref.current, I receive the error
"may be null"

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Here is the component code :

import React, { useState, useRef, useEffect } from "react";

const AudioPlayer = () => {
  // state
  const [isPlaying, setIsPLaying] = useState(false);
  const [duration, setDuration] = useState(0);
  const [currentTime, setCurrentTime] = useState(0);
  const [currentTrack, setCurrentTrack] = useState(null);

  // references
  let audioPlayer = useRef(null); //reference to our audioplayer
  let progressBar = useRef(); //reference to our progressBar
  let animationRef = useRef(); //reference the animation

The ref audioPlayer is declared here and used below to get the duration of the track

  useEffect(() => {
    const seconds = Math.floor(audioPlayer.current.duration);
    console.log(audioPlayer);
    setDuration(seconds);
    progressBar.current.max = seconds;
  }, [
    audioPlayer?.current?.onloadedmetadata,
    audioPlayer?.current?.readyState,
  ]);

  const togglePlayPause = () => {
    const prevValue = isPlaying;
    setIsPLaying(!prevValue);
    if (!prevValue) {
      audioPlayer.current.play();
      animationRef.current = requestAnimationFrame(whilePlaying);
    } else {
      audioPlayer.current.pause();
      cancelAnimationFrame(animationRef.current);
    }
  };

  const whilePlaying = () => {
    progressBar.current.value = audioPlayer.current.currentTime;
    setCurrentTime(progressBar.current.value);
    animationRef.current = requestAnimationFrame(whilePlaying);
  };

  const calculateTime = (secs) => {
    const minutes = Math.floor(secs / 60);
    const returnedMinutes = minutes < 10 ? `0${minutes}` : `${minutes}`;
    const seconds = Math.floor(secs % 60);
    const returnedSeconds = seconds < 10 ? `0${seconds}` : `${seconds}`;
    return `${returnedMinutes} : ${returnedSeconds}`;
  };

  const changeRange = () => {
    audioPlayer.current.currentTime = progressBar.current.value;
    setCurrentTime(progressBar.current.value);
  };

  const changeTrack = (e) => {
    setCurrentTrack(e.target.value);
    console.log(e.target.value);
    togglePlayPause();
  };

  return (
    <>
      <div className="relative flex justify-center my-10 mx-4">
        <img src="/sphere_3D.jpg" alt="sph" width="600" />
        <p className="huit absolute">8</p>
        <input
          className="dots top-40"
          value="/piste1.mp3"
          onClick={(e) => changeTrack(e)}
        ></input>
        <input
          className="dots top-20 left-2/3"
          value="/piste2.mp3"
          onClick={(e) => changeTrack(e)}
        ></input>
      </div>
      <div>
        <audio
          ref={audioPlayer}
          src={currentTrack}
          preload="metadata"
          onCanPlay={(e) => e.target.play()}
        ></audio>
        <button className="mx-5" onClick={togglePlayPause}>
          {isPlaying ? "Pause" : "Play"}
        </button>

        {/* Current time */}
        <div>{calculateTime(currentTime)}</div>

        {/* progress bar */}
        <div>
          <input
            type="range"
            defaultValue="0"
            ref={progressBar}
            onChange={changeRange}
          />
        </div>

        {/* duration */}
        <div>{duration && !isNaN(duration) && calculateTime(duration)}</div>
      </div>
    </>
  );
};

export default AudioPlayer;

>Solution :

Add a type to the ref

const audioElem = useRef<HTMLAudioElement>(null);

make sure you check for a null value before using current:

if (audioElem.current !== null) {
    audioElem.current.focus();
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading