-
-
Notifications
You must be signed in to change notification settings - Fork 467
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update useForm to correctly update/read values in Svelte store #1574
Update useForm to correctly update/read values in Svelte store #1574
Conversation
@weavdale Awesome — thanks for this! I'm going to do some testing, and get #1568 updated after merging this in. |
Awesome! Also Svelte 4 will be released in the next week or two. Not supposed to be much breaking changes but you can start testing with the beta. https://github.com/sveltejs/svelte/releases/tag/svelte%404.0.0-next.1 Rich just did a video recently with the changes coming. There will be a new website with a migration guide but Svelte 4 is mostly a house cleaning release to prepare for Svelte 5. |
Svelte 4 was released today. |
@weavdale sweet! going to give it a try! 🤞 |
Glad you got Svelte 4 support pushed out. Great job! |
@weavdale can you explain how you would use this callback? |
@reinink sure! On line 66 of the current setError(key, value) {
this.setStore('errors', {
...this.errors, // Can't access a reactive store value this way because it may not be updated yet
...(value ? { [key]: value } : key),
})
return this
}, You can't access reactive store values in this way because Svelte may have not updated the internal value yet. You can read a store value using the So in the code above you are trying to spread the existing errors back into the onError: (errors) => {
this.setStore('processing', false)
this.setStore('progress', null)
this.clearErrors().setError(errors) // This will add all cleared errors back into errors variable
if (options.onError) {
return options.onError(errors)
}
}, So I proposed to modify the setStore(key, value) {
store.update((store) => { // current store values gets passed in by the update method
// If "value" is a callback, pass the current store's value into it so it has access to existing values.
// Then the callbacks return value is assigned to _value which is then used to update the store
// with the new value.
const _value = typeof value === 'function' ? value(store) : value
return Object.assign({}, store, typeof key === 'string' ? { [key]: _value } : key)
})
}, With this updated setError(key, value) {
this.setStore('errors', (store) => ({
...store.errors,
...(value ? { [key]: value } : key),
}))
return this
}, Here is a great little video of building your own custom Svelte store using the store contract. Helped me better understand how Svelte's writable store is working under the hood. |
Any updates on the progress of fixing |
The Svelte version of the useForm helper is incorrectly reading values from the Svelte store by using
this
.On line 68 of the
setError
function is directly referencingthis.errors
variable to get a list of the current errors to add back into the store along with any new errors. This is not the correct way to get current values from a Svelte store. You need to subscribe to the store or use the store's update function which passes in the stores current values to the callback. In this case when you callclearErrors
and then immediatelysetError
the internal variablethis.errors
still contains the old errors that were cleared in theclearErrors
function. The store hasn't updated them yet.With this PR I updated the
setStore
function to allow thevalue
parameter to be a callback (in addition to string and object) that passes in the current store values. This allows thesetError
andclearErrors
function to have access to the current store values by using the callback.This should also fix #1521