Svelte: How to handle the custom writtable store's async init's promise in the component?
I have several Svelte components and a custom writtable store. The store has an init
function which is async
and which fills the store's value with some REST API's db's table's data. My components must all subscribe to this store by using autosubscription. At subscription, init
must be called. The global idea is to implement CRUD operations on the db with CRUD operations on the store (usefull to show the store's value, i.e. the db's table, with reactivity).
As init
is async
and, thus, returns a promise, I need to .then .catch
it in my components. But since I use autosubscription (by prefixing the store name with $
), how can I do that?
For example: App.svelte
(the component):
<script>
import { restaurant_store } from './Restaurant.js'
export let name
</script>
<main>
<!--- I need to handle the promise and rejection here -->
{#each $restaurant_store as restaurant}
<li>
{restaurant.name}
</li>
{/each}
</main>
Restaurant.js
(the store):
import { writable } from 'svelte/store'
export function createRestaurantsStore() {
const { subscribe, update } = writable({ collection: [] })
return {
subscribe,
init: async () => {
const response = await fetch('http://localhost:1337/restaurants')
if(response.ok) {
const json_response = await response.json()
set({ collection: json_response })
return json_response
}
throw Error(response.statusText)
},
insert: async (restaurant) => {
const response = await fetch('http://localhost:1337/restaurants', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(restaurant)
})
if(response.ok) {
const json_response = await response.json()
update(store_state => store_state.collection.push(json_response))
return json_response
}
throw Error(response.statusText)
},
update: async (restaurant, id) => {
const response = await fetch('http://localhost:1337/restaurants/' + id, {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(restaurant)
})
if(response.ok) {
const json_response = await response.json()
update(store_state => {
const current_id = store_state.collection.findIndex(e => e.id === id)
store_state.collection.splice(current_id, 1, json_response)
})
return json_response
}
throw Error(response.statusText)
}
}
}
export const restaurant_store = createRestaurantsStore()
Svelte provides a built-in mechanism to handle the possible states of promises within your template, so the same could look like this:
<main>
{#await restaurant_store.init()}
<p>waiting for the promise to resolve...</p>
{:then}
{#each $restaurant_store as restaurant}
<li>
{restaurant.name}
</li>
{/each}
{:catch error}
<p>Something went wrong: {error.message}</p>
{/await}
</main>
Checkout the REPL for a live example.
'개발하자' 카테고리의 다른 글
how can we add project number from variable in terraform gcp resource iam binding (0) | 2022.11.14 |
---|---|
Kubernetes 시크릿 볼륨 대 변수 (0) | 2022.11.14 |
Docker-Compose를 사용하여 Jupyter 노트북을 시작할 때 Docker 컨테이너 내부의 콘다 환경 활성화 (1) | 2022.11.14 |
How to close Drawer upon button click(close) in flutter? (0) | 2022.11.13 |
Flutter web asset images not displaying when deployed to web server (0) | 2022.11.13 |