I am trying to solve front-end development libraries projects using React from Freecodecamp.
In Drum Machine App, I am able to replicate almost all the functions but there is a bug and I am not able to identify that.
So, there are 2 set of sounds and there is a checkbox. When checkbox is not checked(default) Set 1 Sounds are played and when checkbox is checked Set 2 sounds are played.
There are 2 ways sounds are generated. By mouse click and by key press[Q,W,E,A,S,D,Z,X,C].
The problem is when the checkbox is checked and I’m trying to generate sound by key press only [C,D] are working rest are showing error cannot set properties to NULL. When checkbox is unchecked all keydown event are working properly.
This is the problem statement : https://www.freecodecamp.org/learn/front-end-development-libraries/front-end-development-libraries-projects/build-a-drum-machine
And here is my code:
App.js
import "./styles.css";
import React, { useState, useEffect } from "react";
import { bankOne, bankTwo } from "./Sounds";
import ReactFCCtest from "react-fcctest";
const KeyboardKey = (props) => {
const handleKeyDown = (e) => {
if (e.keyCode === props.sound.keyCode) {
props.play(props.sound.id, props.volume, props.power);
}
};
useEffect(() => {
document.addEventListener("keydown", handleKeyDown);
}, []);
return (
<button
className="drum-pad"
id={props.sound.keyTrigger}
onClick={() => props.play(props.sound.id, props.volume, props.power)}
>
<audio className="clip" id={props.sound.id} src={props.sound.url} />
{props.sound.keyTrigger}
</button>
);
};
const Keyboard = (props) => {
return props.sounds.map((sound) => (
<KeyboardKey
play={props.play}
sound={sound}
power={props.power}
volume={props.volume}
/>
));
};
export default function App() {
const [power, setPower] = useState(true);
const [bank, setBank] = useState(false);
const [volume, setVolume] = useState(0.5);
const [sounds, setSounds] = useState(bankOne);
const [soundName, setSoundName] = useState("");
const play = (key, volume, power) => {
if (power) {
setSoundName(key);
console.log(key);
const audio = document.getElementById(key);
console.log(audio);
console.log(volume);
audio.currentTime = 0;
audio.volume = parseFloat(volume);
audio.play();
}
};
const handleVolumeChange = (e) => {
if (power) {
setVolume(e.target.value);
}
};
const handleBankChange = (e) => {
if (power) {
setBank(!bank);
setSounds(e.target.checked ? bankTwo : bankOne);
}
};
const handlePowerChange = (e) => {
setPower(!power);
};
return (
<>
<ReactFCCtest />
<div id="drum-machine">
<div id="display"></div>
<Keyboard play={play} sounds={sounds} volume={volume} power={power} />
{power && (
<>
<p>Bank</p>
<label className="switch">
<input
type="checkbox"
defaultChecked={bank}
onChange={(e) => handleBankChange(e)}
/>
<span className="slider rounded" />
</label>
<p>{soundName}</p>
<h3>Volume: {Math.round(volume * 100)} %</h3>
<input
max="1"
min="0"
type="range"
step="0.01"
value={volume}
onChange={(e) => handleVolumeChange(e)}
/>
<br />
</>
)}
<p>Power</p>
<label className="switch">
<input
type="checkbox"
defaultChecked={power}
onChange={(e) => handlePowerChange(e)}
/>
<span className="slider rounded" />
</label>
</div>
</>
);
}
Sounds.js
export const bankOne = [
{
keyCode: 81,
keyTrigger: "Q",
id: "Heater-1",
url: "https://s3.amazonaws.com/freecodecamp/drums/Heater-1.mp3"
},
{
keyCode: 87,
keyTrigger: "W",
id: "Heater-2",
url: "https://s3.amazonaws.com/freecodecamp/drums/Heater-2.mp3"
},
{
keyCode: 69,
keyTrigger: "E",
id: "Heater-3",
url: "https://s3.amazonaws.com/freecodecamp/drums/Heater-3.mp3"
},
{
keyCode: 65,
keyTrigger: "A",
id: "Heater-4",
url: "https://s3.amazonaws.com/freecodecamp/drums/Heater-4_1.mp3"
},
{
keyCode: 83,
keyTrigger: "S",
id: "Clap",
url: "https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3"
},
{
keyCode: 68,
keyTrigger: "D",
id: "Open-HH",
url: "https://s3.amazonaws.com/freecodecamp/drums/Dsc_Oh.mp3"
},
{
keyCode: 90,
keyTrigger: "Z",
id: "Kick-n'-Hat",
url: "https://s3.amazonaws.com/freecodecamp/drums/Kick_n_Hat.mp3"
},
{
keyCode: 88,
keyTrigger: "X",
id: "Kick",
url: "https://s3.amazonaws.com/freecodecamp/drums/RP4_KICK_1.mp3"
},
{
keyCode: 67,
keyTrigger: "C",
id: "Closed-HH",
url: "https://s3.amazonaws.com/freecodecamp/drums/Cev_H2.mp3"
}
];
export const bankTwo = [
{
keyCode: 81,
keyTrigger: "Q",
id: "Chord-1",
url: "https://s3.amazonaws.com/freecodecamp/drums/Chord_1.mp3"
},
{
keyCode: 87,
keyTrigger: "W",
id: "Chord-2",
url: "https://s3.amazonaws.com/freecodecamp/drums/Chord_2.mp3"
},
{
keyCode: 69,
keyTrigger: "E",
id: "Chord-3",
url: "https://s3.amazonaws.com/freecodecamp/drums/Chord_3.mp3"
},
{
keyCode: 65,
keyTrigger: "A",
id: "Shaker",
url: "https://s3.amazonaws.com/freecodecamp/drums/Give_us_a_light.mp3"
},
{
keyCode: 83,
keyTrigger: "S",
id: "Open-HH",
url: "https://s3.amazonaws.com/freecodecamp/drums/Dry_Ohh.mp3"
},
{
keyCode: 68,
keyTrigger: "D",
id: "Closed-HH",
url: "https://s3.amazonaws.com/freecodecamp/drums/Bld_H1.mp3"
},
{
keyCode: 90,
keyTrigger: "Z",
id: "Punchy-Kick",
url: "https://s3.amazonaws.com/freecodecamp/drums/punchy_kick_1.mp3"
},
{
keyCode: 88,
keyTrigger: "X",
id: "Side-Stick",
url: "https://s3.amazonaws.com/freecodecamp/drums/side_stick_1.mp3"
},
{
keyCode: 67,
keyTrigger: "C",
id: "Snare",
url: "https://s3.amazonaws.com/freecodecamp/drums/Brk_Snr.mp3"
}
];
PS: Some of my code is from a Tutorial.