Search code examples
javascriptsveltesveltekit

How do I create a state to handle events in my form?


How do I create a state to toggle the buttons in my form between true or false(yes and no)?

I'm trying to handle the state with a function:

const onMutate = (e) => {
        // toggle
        buttonState = !buttonState;

        // Files
        if (e.target.files) {
            formData = {
                ...formData,
                images: e.target.files
            };
        }

        // texts/number/boolean
        if (!e.target.files) {
            formData = {
                ...formData,
                [e.target.id]: buttonState ?? e.target.value
            };
        }
    };

My State:

let buttonState = false;

I put the function (onMutate) in my events:

on:click={onMutate}
on:Change={onMutate}

Ok. I can switch my buttons between yes or no (true or false) with the 'on:click' event, but when I type into the input, I fire the same event and get true or false in my inputs. I know it's an issue about javascript more than Svelte. I know where the problem is:

// texts/number/boolean
            if (!e.target.files) {
                formData = {
                    ...formData,
                    [e.target.id]: buttonState ?? e.target.value
                };
            }

But I don't know how to solve it.


Solution

  • It's pretty hard to decipher what exactly you want to accomplish. But I think I was able to find something that is most likely the root of your issue. Namely that you get true and false in the formData.

    This comes about because you are using the ?? operator. It works the following way (with the example of a ?? b): MDN reference

    • if a is null or undefined then it will return b
    • in all other cases it will return a

    In your case buttonState is neither null nor undefined so, the value of the expression will be the value of buttonState, ie: true or false.

    I can assume that you wanted to use a logic where if the buttonState is true, then include the value of the input, otherwise don't.

    The proper expression for this is (using the conditional ternary operator):

    buttonState ? e.target.value : null

    This will produce the value of the input if buttonState is true, and null if the buttonState is false. You can, of course, use other values instead of null for the false state.


    Some additional notes:

    The buttonState is toggled at each event, including on the onChange event. I don't know if it's intentional but seems odd, that when you type something in an input box your button flips on an off. It would be more logical if the button would have its own event handler which could be as simple as:

    <button on:click={()=> buttonState=!buttonState}>....

    Note #2: It's really useful to people who would like to help you out if you provide a small working mockup in a REPL with and link to it in your question. It's good that you provided some part of your code, but it's still hard to figure out how it all supposed to work. I know it's extra work, but will get you faster and better responses.