bestguy / sveltestrap

Bootstrap 4 & 5 components for Svelte
https://sveltestrap.js.org
MIT License
1.3k stars 180 forks source link

Can a component containing a Sveltestrap Modal load it's own content data `on:opening`? #501

Closed MarkBFamFour closed 1 year ago

MarkBFamFour commented 1 year ago

I am building a project that has Modal information pop-ups. I am struggling with data loading at open - I have each Modal contained in a component, and a single copy of each Modal component included in the main App.svelte so there is no unnecessary duplication in the DOM.

The 'least-worst' way I could find to load the content into the Modal when it loads is to pass a trigger event through around 6 layers of components to a method in the App.svelte that then triggers an async function that gets the data via API request outside of the Modal that sets the data and isOpen property of the Modal component and shows it with the content in place. but this seems really untidy.

Here is an example: https://svelte.dev/repl/5fbbd2737c2c4d5686d6ffde8151735b?version=3.49.0

What I am wondering is if there is a better way to pass the isOpen property and, for example, a recordID (either by event-passing or using a $store to store state, I have used both successfully to some extent with Modals) to the Modal. It would then trigger an action to have the Modal component execute an API request on:opening that then populates the Modal. This way nothing external is responsible for the API negotiation and the Modal is self contained.

Like this example REPL: https://svelte.dev/repl/0eb31ff127bd4a8189f7c2ee9746d339?version=3.49.0

The problems I seem to have are:

P.S. The REPLs don't function because I think the bug with sveltestrap, popper.js and Vite but you can see the code at least

MarkBFamFour commented 1 year ago

Okay, so I solved this myself with this idea:

I added a separate let loaded: boolean variable into the Modal component. This loaded var is used with an {#if loaded && record } in the component HTML to prevent the content drawing until the correct time. An async function triggered by the on:opening event requests the data, and when that Promise is resolved the loaded variable is flagged true, meaning the modal draws it's content only once the data is loaded. Additionally in the toggle() method that allows the modal to hide itself (on blur or clicking a close button for e.g.) resets loaded =false, once again inhibiting the HTML display.

I threw it in a REPL here: https://svelte.dev/repl/0eb31ff127bd4a8189f7c2ee9746d339?version=3.49.0