Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I map a concatenated value for this state, without it being passed as a string?

I'm new to Javascript.

I'm building this drumpad and I want to be able to switch between different soundpacks.

The sounds are imported from a separate file and the state is written like this:

import * as Sample from '../audiofiles/soundfiles'

    const drumpadData = [
        {
            // other stuff
            soundfile: Sample.sound1a
        },

If I want to load a different soundpack, I have to change the state so the last letter (a,b,c) gets changed, so instead of Sample.sound1a, it would have to be Sample.sound1b. this is the function i wrote (on App.js):

changeSamples(id) {
    let choice = document.getElementById("select-samplepack").value
    this.setState(prevState => {
        const updatedData = prevState.data.map(item => {
            let newSoundfile = "Sample.sound" + item.id + choice
            item.soundfile = newSoundfile
            return item
        })
        return {
            data: updatedData
        }
    })
}  

It works, as in the value gets changed, but instead of react interpreting that and finding the correct import, the value of soundfile just stays as a string like "Sample.soundb1", so I get a load of media resource errors.

https://aquiab.github.io/drumpad/ heres the website, you can check the console to see the error, you have to load a different soundpack to reproduce the error.

https://github.com/aquiab/drumpad and here are the files:

I've thought of some ways of cheesing it, but I want the code to stay as clean as I can make it be.

like image 492
FES Avatar asked Nov 18 '25 03:11

FES


1 Answers

Well that's because it is in fact a string. When you do:

"Sample.Sound" + item.id + choice you are doing type coersion. In JavaScript, that means you are converting the value of all data-types so that they share a common one. In this case your output resolves into a string. This will not be effective in finding the right sound in your dictionary.

Instead, what you need is bracket notation: Object[property] Within the brackets we can define logic to identify the designated key belonging to the Object.

For example: Sample["sound" + item.id + choice] would evaluate to Sample["sound1b"] which is the same as Sample.sound1b

changeSamples(id) {
    let choice = document.getElementById("select-samplepack").value
    this.setState(prevState => {
        const updatedData = prevState.data.map(item => {
            item.soundfile = Sample["sound" + item.id + choice]
            return item
        })
        return {
            data: updatedData
        }
    })
}  
like image 111
Chris Ngo Avatar answered Nov 19 '25 17:11

Chris Ngo