I've got the following route:
- routes
- artists
- [slug]
- new
- +page.server.js
- +page.svelte
where new/+page.svelte
is the following:
<script>
import ArtistForm from "../../../components/forms/ArtistForm.svelte";
/* data returned from actions function in +page.server.js */
export let form;
</script>
<ArtistForm formData={form} mode="new" />
and +page.svelte
simply has the action that has to be performed when the form is submitted:
export const actions = {
default: async ({ request, fetch }) => {
const artistAPI = new ArtistAPI(fetch);
const data = Object.fromEntries(await request.formData());
const artist = artistDTO(data);
// if errors returned from building the DTO (validation errors) then return the object.
if (artist?.errors && !emptyObject(artist.errors)) {
return {
"data": artist.data,
"errors": artist.errors,
};
}
const response = await artistAPI.post(artist);
if (response.status == 200) {
throw redirect(302, '/artists')
}
return {
"data": artist.data,
"errors": response.errors,
}
}
};
Now, this works fine on its own. Whenever I access artists/new
I can create new artists.
The issue is the following:
I've got a routes/records/new
route. When creating a record I want to allow an user to dynamically create an artist via a modal if the artist doesn't exists.
To do so I'm loading a modal and within the modal I'm loading the <ArtistForm>
component. The component has a <form>
element and a button to submit the form.
This is the piece of code within routes/records/new
where the component is loaded:
{:else if activeStep == "CreateArtist"}
<div>Artist does not exist, please add it.</div>
<ArtistForm loadedAsModal={ true } />
<div class="mt-7 flex justify-center">
<button class="btn btn-outline btn-primary" type="submit" on:click={handleSubmit}>Create Artist</button>
</div>
{/if}
The problem is when I click on the save button. When the form within the modal is submitted is calling the action defined in routes/records/new/+page.server.js
. The artist's action
is not triggered which I think is correct since I'm loading the component in routes/records/new
but the action lives in routes/artists/new/+page.server.js
.
I was thinking to perhaps add a callback method passed as prop to <ArtistForm>
but then I'd have to duplicate the logic so the callback can get the data from the form and perform the POST request.
Is there any way around this without (or with the minimum) code duplication?
/artists/new/
solves the problem?on:submit|preventDefault="{handleSubmit}"
so I'm expecting to be able to print the value ofform
object inhandleSubmit
which is not happening. If I remove theon:submit
then I see it when doing$: console.log(form)
on:submit|preventDefault="{handleSubmit}"
, then you can't access form inhandleSubmit
.handleSubmit
will be called before the request is sent to the server, andform
will be populated with data after the web browser has received the response for that request. So you have to use reactivity ($:
syntax) to listen for whenform
has obtained a new value if you want to "listen" to the response.use:enhance
and calling a callback method with the data returned inresults
.