felte icon indicating copy to clipboard operation
felte copied to clipboard

svelte / setFields not working

Open tiagoapp opened this issue 1 year ago • 6 comments

Describe the bug

Essentially I'm having troubles get the data back in the inputs.

const { form, data, setFields, reset, setData, setInitialValues, handleSubmit } = createForm({
initialValues: {
     name: '',
}
})

const onClickEdit = async (id: string) => {

	const { data, error } = await categories.find(id);

        // this doesn't change the data on the input
	setData({
		name: data?.name,
	});

        // this doesn't change the data on the input
       setFields('name', data?.name, true)

       // this does work and I get data on inputs, but can't use the reset() afterwards to get back to blank state
       setInitialValues({
		name: data?.name,
	});
}

Basically trying to get the field to load the data on editing

<form class="flex flex-col" use:form>
	<label for="name">Name</label>
        <input type="text" name="name" />
</form>

Which package/s are you using?

felte (Svelte)

tiagoapp avatar Mar 04 '23 18:03 tiagoapp

Hey! Do you have a REPL reproduction? This works for me in the REPL: https://svelte.dev/repl/bb45eaf5b54745d98ea074167e278bdd?version=3.55.1

What are you trying to do?

pablo-abc avatar Mar 06 '23 21:03 pablo-abc

@pablo-abc here is a modified version of something I'm trying to do with felte's setFields and havent been able to do it gracefully.

https://svelte.dev/repl/284ff1438c6a4990ac370b2db27efaee?version=3.55.1

To workaround this I had to call setFields for both inputs.

canastro avatar Mar 18 '23 09:03 canastro

Seems setFields is also broken for Solid. Not sure whether worth opening a separate issue since all libs use the same core functionality?

aryzing avatar Oct 19 '23 15:10 aryzing

Seems the functionality is broken when the form isn't yet rendered. Attempting to set the fields of a form that's not yet connected to the DOM will throw no errors, but have no effect.

It may be necessary to create the form before connecting it to the dom, for example, to pass to other components or to prefill it with data before rendering it to the user.

aryzing avatar Oct 19 '23 15:10 aryzing

That is correct! A form needs to exist and be connected before anything else happens.

This has been on my head for a while and it seems I just found why this is happening. The original issue seems to be due to a race condition. Both felte itself and the code in the example are waiting for input at around the same time. If you force the input handler to wait a bit (e.g. setTimeout), or, more cleanly use a $: to guarantee the value has already been updated internally it works.

For this specific example, using $: setFields('test', $data.name?.toUpperCase()); instead of the handleChange function works as expected.

Checking if there's a way to handle this scenario is taking me a while so apologies for that....

pablo-abc avatar Oct 19 '23 15:10 pablo-abc

A form needs to exist and be connected before anything else happens.

Thanks for clarifying. How does the lack of DOM elements prevent the state from being updated? Couldn't the fields read their values from the store once they're connected to the DOM?

aryzing avatar Oct 19 '23 17:10 aryzing