Drum Machine onClick returning null

I’m currently working on the Drum Machine but have run into an odd error. Currently my drum machine works if you type the letters on the pad, but if I were to try to set an onClick for the divs, the compiler will tell me that I am passing in a null reference.

“Uncaught TypeError: Cannot read properties of null (reading ‘play’)”
This error occurs on line 59.

//...

handleNote(letter) {
    document.getElementById(letter).play();
    this.setState({
      pressed: document.getElementById(letter).parentNode.id
    })
  }

render() {
    
    return (
      <div id="drum-machine">
        
        <div id="box">
          
          <div class="drum-pad" id="Sound1" onClick={this.handleNote("Q")}>
            Q<audio id="Q" class="clip " src="https://s3.amazonaws.com/freecodecamp/drums/Heater-1.mp3"/>
          </div>

//...more divs.

I found this article online: TypeError: document.getelementbyid(...) is null
And I thought it might be relavent, but it seems odd that key presses would work fine, but not the onClicks. What is it that I am missing?

Challenge: Build a Drum Machine

Link to the challenge:

This isn’t quite right. You can’t invoke the handleNote function here by passing in the letter. The onClick property should be set to a function (which is just the function name itself without the parens).

Look at how you have defined the handleKeyPress function:

handleKeyPress(event)

You are using addEventListener to add a keydown listener:

document.addEventListener("keydown", this.handleKeyPress)

Notice how you are just passing the function name as the second argument. This is basically the same thing that is happening when you use onClick on an element.

Also notice that in handleKeyPress the event object is automatically passed into the function and then you query a property on it (keyCode) in this case) to determine which sound to play. It will work the same way with handleNote (but you won’t use keyCode since this isn’t a keypress event).

1 Like

Thank you so much! I haven’t gone back to look at it just yet, but I think I see what you’re getting at and I can’t believe I didn’t think of it sooner.

Just to be clear, if you want to pass an argument to the handler you have to wrap it inside a function. Otherwise, the way you have it now the function is just invoked immediately when the code runs.

onClick={() => this.handleNote("Q")}
2 Likes