I have had a little look at your code. There are a few things that you might want to look at:
You are calling the playSound function from the render function- You want to sound to be playing when the user clicks or presses a key, not when the display updates. It is a subtle difference, but you current setup gives an error when the component mounts.
As you have sounds working for key presses and not when the user click, this points to an error in your handleClickPlay function. You need to change the currentSound in setState to source not text. If you look at the console, you will see that there is an error coming back from the server because your link has “sounds.” at the end.
If you look at your handleKeyPress function, you could simplify it:
let currentSound = soundFilesNamesAndKeys[event.key];
You would need to handle transforming the text to lowercase and what to do if there is no value in the object as it will come back undefined, but it might help keep your code DRY.
Hope this is of some use and points you in the right direction
As you have sounds working for key presses and not when the user click, this points to an error in your handleClickPlay function. You need to change the currentSound in setState to source not text. If you look at the console, you will see that there is an error coming back from the server because your link has “sounds.” at the end.
After changing that, the click triggers the sound ok.
I’ve been making some changes, thanks to your suggestions.
It was a great idea to simplify the handleKeyPress function. Also, although it still calls the playsound from render, there is a conditional test, so it only tries to reproduce the sound if there is a filename to play assinged to the respective property in the state.
It doesn’t pass one test:
When I press the trigger key associated with each .drum-pad, the audio clip contained in its child
If you have a moment (whenever it could be), would you tell me what you think, please?
Here is a previous version that works and passes the tests
I think the source of the problem is that the test suite creates an event to simulate a keypress, whereas a keydown event is trigger when you press a key. Not quite sure how it is all working to be honest and why you original project works but this doesn’t, but the example project uses a keyCode (eg. W is 81) instead of a letter. If you put console.log(event) at the top of the handleKeyPress function and compare the result from pressing a key to running the tests, you will see the difference.
In terms of the rest of your code, I think it’s quite nice. If it were my code then I might make the following changes:
Your “Another idea code” is, I think, much better than the current code as it is easier to read and it only evaluates isValidKey once.
Something I learnt from the React docs (sorry I can’t remember which part) was to keep things stored in state to a minimum. You only have one thing that is changing which is the sound, so all you need to have in the state is some kind of reference to the sound. If you know what sound is the current one, you can then work out what the link or text should be. There are several ways this can be achieved, but as an example using you current display text as a model, if you state contains the link then:
this.setState({currentSound: link});// easy to manage state
render() {
let text = this.state.currentSound + " sounds." // only one place to manage display text
return <p>{text}</p>
}
I can’t see anything you playSound function is returning to render, so assuming you want to keep the playSound call in your render function, you could do something like this:
render() {
if (soundNeedsToBePlayed) {
playSound();
}
return (
// stuff to display
)
}
Hope this helps and that I haven’t waffled on too much
You were very helpful! Thanks to your observations I could make progress.
Apparently the test uses a keyboard event which has an undefined key property. So, I used keyCodes, although it is a deprecated property.