Reputation: 1272
I am refactoring a React app that loads the language labels from a json file on the server. The data is pulled from the server using an Ajax call, which updates a store that contains all the language labels. Here is some code illlustrating the problem.
app.js
<script>
import { storeLang, getLangLabels } from './store'
// get labels from server
getLangLabels()
// set language labels in a reactive variable
$: LABELS = $storeLang.labels
</script>
<div>
<h2>{LABELS.title}</h2>
</div>
Here is how the store is setup. The ajax call updates the store with the labels.
store.js
import { writeable } from 'svelte/store'
export const storeLang = writeable({})
export const getLangLabels = () => {
return fetch('lang.json').then( data => {
storeLang.set(data);
})
}
However, when I run the application I do not have access to the LABELS variable yet, nor it is updated when the fetch call is resolved. Here is the error message.
Uncaught ReferenceError: Cannot access 'LABELS' before initialization
The way I solved this problem in React was to render the entire <App />
only after the language labels where fetched from the server. I have not figured out a way to solve this using Svelte.
Please advise.
Following @tehshrike recommendation, I setup the getLang
as an async function and using an await block on the App.svelte
component, which is the entry point of the app. This way, when the promise resolves after getting the language labels, the App renders (code abbreviated for illustration purposes).
App.svelte
<script>
import { getLang } from './lang/store.js';
let promise = getLang();
</script>
{#await promise}
Loading language labels
{:then value}
// we don't use the returned value because the labels are stored in
// the store and the subscribed components react accordingly
<Header />
<Sidebar />
<Main />
{:catch}
Error resolving promise
{/await}
Upvotes: 2
Views: 1387
Reputation: 10074
If you put your promise into the store itself, instead of waiting for the promise to resolve before putting the value into the store, you can use an await block and reference $storeLang.labels
without needing to set up a reactive declaration inside your component.
Upvotes: 2