0

I am using Svelte to create a small personal project. I have this HTML code:

{#await card}
    <p>...waiting</p>
{:then card}
    <Card {card}/>
{/await}

card is an element of a list that is used by the component Card (notice the capital letter). To get the list of cards I fetch a JSON file. To do so I have created this function:

async function loadJson(path) {
    const response = await fetch(path);
    const cards = await response.json();
    return cards; 
}

This code will return a promise. I need to manipulate the list returned once the promise is resolved to get one card of the list. My first thought was to do it like this:

let cards = loadJson('./path.json')
let card = cards[0]

The problem with this approach is that card will be undefined because this code is executed before the promise is resolved. I thought of creating an async function main that looked like this:

async function main(){
    let cards = await loadJson('./hsk1.json')
    let card = cards[0]
}

The problem is that now card is inside the scope of main and the Card component can't read it. If I declare card outside the main function the svelte await block will not wait because card is not a promise. I can make the main function to return a value, but that looks really ugly:

async function main(){
    let cards = await loadJson('./hsk1.json')
    let card = cards[0]
    
    return card;
}
    
let card = main();

Another option could be to send the list cards to the Card component and select the card there, but I would like to avoid it if possible.

I do not have any experience with JS neither with Svelte, so maybe I am missing something really basic. Right now I can't think of a decent way of solving this problem.

Thanks!

edoelas
  • 317
  • 2
  • 13
  • *I can make the main function to return a value, but that looks really ugly:* Won't work either, it'll still return a Promise. You need either a `.then` or `await` in the caller of `loadJson`. The `main` function doesn't really accomplish anything useful. – CertainPerformance Sep 04 '21 at 14:17
  • I think it works. The main point of creating the main function is to be able to put an await when I call loadJson. I need to do it because I can't put an await outside an async function. – edoelas Sep 04 '21 at 14:42
  • Won't really help anything, though - then `main` will return a Promise, and you're back to where you started. Ditch it and just use `.then`. – CertainPerformance Sep 04 '21 at 14:43
  • Okay, thanks, I think I get what you were suggesting. Just to make sure I understand it, is it this? let card = loadJson('./hsk1.json').then(value => { return value[0] }) – edoelas Sep 04 '21 at 14:53
  • Returning it doesn't accomplish anything - just put whatever you need to do with it inside the `.then`. Eg `.then(processHSK)` and have `processHSK process it – CertainPerformance Sep 04 '21 at 14:54
  • But I need to return it so card is in the global scope and the svelte component can read it – edoelas Sep 04 '21 at 14:55

0 Answers0