How to get the drum machine to play sounds

I’ve got my drum machine to display the correct sound name when keys are pressed but not to play the sound when they are pressed. I tried setting the sound to the url for the sound and doing sound.play() but it says sound.play isn’t a function. here’s my code.

 let sounds = {
  q: "https://s3.amazonaws.com/freecodecamp/drums/Heater-1.mp3",
  w: "https://s3.amazonaws.com/freecodecamp/drums/Heater-2.mp3",
  e: "https://s3.amazonaws.com/freecodecamp/drums/Heater-3.mp3",
  a: 'https://s3.amazonaws.com/freecodecamp/drums/Heater-4_1.mp3',
  s: 'https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3',
  d: 'https://s3.amazonaws.com/freecodecamp/drums/Dsc_Oh.mp3',
  z: 'https://s3.amazonaws.com/freecodecamp/drums/Kick_n_Hat.mp3',
  x: 'https://s3.amazonaws.com/freecodecamp/drums/RP4_KICK_1.mp3',
  c: 'https://s3.amazonaws.com/freecodecamp/drums/Cev_H2.mp3' 
}
let names = {
  q: "Heater-1",
  w: "Heater-2",
  e: "Heater-3",
  a: 'Heater-4_1',
  s: 'Heater-6',
  d: 'Dsc_Oh',
  z: 'Kick_n_Hat',
  x: 'RP4_KICK_1',
  c: 'Cev_H2' 
}

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
    display: "display"
    }
  }
  
  
  componentDidMount () {
    document.addEventListener("keydown", this.handleKey)
  }
  
  handleKey = e => {
    this.playSound(e.key)
    this.updateDisplay(e.key)
  }
  playSound = key => {
    let sound = sounds[key];
    //sound.play()    
  }
  updateDisplay = key => {
    this.setState({
      display: names[key]
    })
    console.log(this.state)
  }
  
  render () {
    return (
    <div id="drum-machine">
        <h1>YOU SEE MEEEE!??</h1>
      <p>Word I should really see some words here  up</p>
        <Display display={this.state.display}/>
    </div>
    )
  }
}

const Display = (props) => {
  console.log(props)
  return (
  <div>
    <input value={props.display} />
      <Buttons />
  </div>
  )
}

const Buttons = (props) => {
  
  return (
    <div>
    <button className="drum-pad" value="Heater1"> Q </button>
      <button className="drum-pad" value="Heater2"> W </button>
      <button className="drum-pad" value="Heater3"> E </button>
      <button className="drum-pad" value="Heater4"> A </button>
      <button className="drum-pad" value="Heater6"> S </button>
      <button className="drum-pad" value="Dsc_Oh"> D </button>
      <button className="drum-pad" value="Kick_n_Hat"> Z </button>
      <button className="drum-pad" value="RP4_KICK_1"> X </button>
      <button className="drum-pad" value="Cev_H2"> C </button>
    </div>
  )
}




ReactDOM.render(<App />,document.getElementById('root'));

here a link https://codepen.io/dmoneyballer/pen/aMEPxY?editors=0010

I see that in the example he’s grabbing an object from the document. Is that how I have to do it? I commented out the sound.play so it would update display. It definetly has to do with the fact that I don’t have an audio element. So I’m playing with that now.

Hi.
I think it wants to see the <audio className="clip"> inside of each .drum-pad (inside the map button).
That should help you pass tests #4 & #5, and lead you in the right direction…

I hope it helps a little…

1 Like

Someone at a meetup told me that they had a similar problem. I that if I used Async on my handle click and await setState it totally works.

  click = async (e) =>{
    let name = e.target.innerHTML.toUpperCase().trim();
    await this.setState({
      key: name
    });
    this.playSound(name)
    this.updateDisplay(name)
  }

^ that’s the code that got the click to work.

This looks great! Congratulations!

async and await are still new concepts to me. Thank you for sharing.

1 Like