Help: Drum Machine project test failing

Hi,

So here’s my code that I am working on. This is for the drum machine project. I have successfully created the buttons and the audio file is played when I click them. I am not able to pass test no 5 in the compiler which says:

  1. When I click on a .drum-pad element, the audio clip contained in its child

Here’s the code:

import React from "react";
import ReactDom from "react-dom";
import ReactPlayer from "react-player";

const sounds = [
  {
    idnum: "1",
    id: "Q",
    src: "https://s3.amazonaws.com/freecodecamp/drums/Heater-1.mp3",
  },
  {
    idnum: "2",
    id: "W",
    src: "https://s3.amazonaws.com/freecodecamp/drums/Heater-2.mp3",
  },
  {
    idnum: "3",
    id: "E",
    src: "https://s3.amazonaws.com/freecodecamp/drums/Heater-3.mp3",
  },
  {
    idnum: "4",
    id: "A",
    src: "https://s3.amazonaws.com/freecodecamp/drums/Heater-4_1.mp3",
  },
  {
    idnum: "5",
    id: "S",
    src: "https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3",
  },
  {
    idnum: "6",
    id: "D",
    src: "https://s3.amazonaws.com/freecodecamp/drums/Dsc_Oh.mp3",
  },
  {
    idnum: "7",
    id: "Z",
    src: "https://s3.amazonaws.com/freecodecamp/drums/Kick_n_Hat.mp3",
  },
  {
    idnum: "8",
    id: "X",
    src: "https://s3.amazonaws.com/freecodecamp/drums/RP4_KICK_1.mp3",
  },
  {
    idnum: "9",
    id: "C",
    src: "https://s3.amazonaws.com/freecodecamp/drums/Cev_H2.mp3",
  },
];

class Button extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      audioSource: "not clicked",
    };

    this.soundOn = this.soundOn.bind(this);
  }
  soundOn = (info) => {
    var audio = new Audio(info.src);
    audio.play();
  };

  
  render() {
    const buttonData = sounds.map((info) => (
      <button
        className="drum-pad"
        id={info["idnum"]}
        onClick={() => this.soundOn(info)}
      >
        {info["id"]}
        <audio
          src={info.src}
          className="clip"
          id={info.id}
          type="audio/mp3"
        ></audio>
      </button>
    ));
    return buttonData;
  }
}

export default Button;

Any help would be appreciated.

Thanks!

I think the ‘child’ in the user story is a DOM node, so you have to use the html5 audio tag. Also when write here your code try to use the specific markdown to get text properly formatted. Good luck

Hi,

Thanks for the input. I shall format it properly next time.
But, by the looks of it, I have used the HTML5 audio tag.

Its there inside the element.

I think you do not play that one, you play the another one created inside the fn soundOn

Yes, looking at it, I am activating the button onClick method which is activating the audio file.
Can you please help me in figuring out how to play the audio element.
I am pretty stuck up here.

Have a look to the react documentation about ref

Been searching for hours.
Any reference links?

No idea as to how to do it. It would be great if you can help me with the code.

I think it should be 2 or 3 lines of code.
You have to create a ref, attach it to the html audio, and use the ref to play it inside the onSound fn. Very simple

This is what I’ve done now.
Am I even on the correct path?

inputAudio = React.createRef(sounds.src)
  
render() {
    const buttonData = sounds.map((info) => (
      <button
        className="drum-pad"
        id={info["idnum"]}
        onClick={() => this.soundOn(info)}
      >
        {info["id"]}
        <audio
        ref={this.inputAudio}
          src={info.src}
          className="clip"
          id={info.id}
          type="audio/mp3"
        ></audio>
      </button>
    ));

I don’t believe you can use ref for this. Then it will always play the last audio file in the array. But just to cover it. you would use React.createRef() in the constructor. Add the ref attribute to the element and get to it using the current property.

Condensed pseudo example:

constructor(props) {
  this.audio = React.createRef();
}

handlerFn () => {
  this.audio.current.play();
}

<audio
  ref={this.audio}
/>

You can use the event and get to the child element and call play on it.

Function:

soundOn = event => {
  console.log(event.target.firstElementChild);
  const audioElement = event.target.firstElementChild;
  audioElement.play();
};

Function call:

onClick={this.soundOn}
1 Like