I have the following minimal example:
Component A:
<script lang="ts">
import {tick} from 'svelte';
import LocationSelector from './LocationSelector.svelte';
let locationSelector: LocationSelector;
let selectedCompany: string;
async function updateAvailableLocations(){
await tick();
locationSelector.setAvailableLocations(selectedCompany);
}
$: selectedCompany, updateAvailableLocations();
</script>
<input type="text" bind:value={selectedCompany} />
{#if selectedCompany}
<LocationSelector bind:this={locationSelector}/>
{/if}
LocationSelector.svelte component:
<script lang="ts">
let availableLocations: Locations[];
export function setAvailableLocations(type: string) {
for (const location of availableLocations ) {
if(company == location.company) {
.... (Code to set the available locations in the dropdown)
}
}
}
onMount(async () => {
try {
availableLocations = await api.getAllLocations();
} catch (error) {
consolo.log("...")
}
}
</script>
...
My problem is that when the selectedCompany
value is going from undefined or and empty string to a value and therefore the "if" is true the LocationSelector.svelte component will be shown but the onMount
function of the LocationSelector.svelte will be called after the setAvailableLocations
function. Which means the availableLocation
is empty and therefore useless.
Why is setAvailableLocations
called after the onMount
in this case?
I wrote an even more minimal example that demonstrates that the onMount
callback gets called before the method. Check the box, look in the console, and see for yourself.
The reason availableLocations
is empty in your example is because await api.getAllLocations()
hasn't finished yet. onMount
doesn't make any guarantee about async callbacks running to completion.
The way I'd fix this is to make selectedCompany
a prop rather than a value that must be passed to a method, then use a reactive statement that checks when selectedCompany
and availableLocations
are both ready:
$: if (selectedCompany && availableLocations.length) {
setAvailableLocations(selectedCompany);
}