Why is this data inconsistently applied per item?

This is easier to do with async and await functions, I got it done quite quickly. However, I wanted to try doing it without async as I’m learning.

  1. I don’t understand the way data is fetched and applied in the “showPromiseScores” function where data is fetched and I try to append it as the “link” property of an object. Can you help me understand why this works inconsistently?
  2. Is it better to use async await, or not?

Here’s the code to get the data:

    function getPromiseScores () {
        let scoresForMember = currentMember.getMember()
            .then( results => {
                let r = wixData.query('Scores').eq("_owner", results._id).find();
                return r;
            });
        return scoresForMember;
    }

    function getPromisePatternContext (p) {
        const qResult = wixData.query('Patterns').eq("_id", p).find();
        return qResult;
    }

    function showPromiseScores () {
        let scoreResults = getPromiseScores()
            .then( scoreRes => {
                if (scoreRes && scoreRes.length > 0) {
                    let scoredItems = scoreRes.items;
                    let context;
                    for (let i = 0; i < scoreRes.length; i++) {
                        context = getPromisePatternContext(scoredItems[i].scoredPattern)
                            .then( data => {
                                scoredItems[i].link = data.items[0]['link-patterns-title'];
                                return scoredItems;
                            });
                    } 
// ^^ THE LOOP CODE ABOVE SEEMS TO BE INCONSISTENTLY APPLIED TO THE DATA OUTPUT
                    console.log(context);
                    return context;
                    
                } else { 
                        console.log("Getting pattern title didn't work");
                }
            });
        return scoreResults;
    }

Here you can see data is added to the “link” property seemingly randomly, sometimes all/some/none of the fetched data has the link data applied:

What am I doing wrong?

Async/Await and .then() are similar but do work a little differently in the way that they stop function execution. Not sure what others passing through will weigh in, but I find async/await to be a cleaner way to handle promises because it’s much easier to read/tell what’s going on.

It’s hard to tell without running it/debugging but i think your console.log(context) being outside of the .then() might be the issue because it looks like you need that promise to resolve to be able to update the context.

Here are some more resources we have on promises and there is a boatload of info on the internet about async/await vs .then() and more information from users in the forum too. Let me know if you need anymore information!

Promises Post
Promises Docs

Video on async basics

Thank you for your helpful reply @amandam . I can confidently move ahead with async as my approach, it’s easier for a newbie like me to understand anyway.

Below is the last piece of the code where the data is rendered into the UI (you will also see the source code for the console.log). Because the object’s link property is sometimes empty the Repeater throws an error. It seems odd, as I thought I handled the promise correctly with a .then call.

Any idea on what’s going on? It’s bugging me because I thought I did everything correctly.

    let scores = showPromiseScores();
    
    scores.then(items => {
        $w("#repeater1").data = items;
        $w("#repeater1").show();
    });

    $w("#repeater1").onItemReady(($item, itemData) => {
        console.log(JSON.stringify(itemData));
        $item("#text3").text = itemData.title;
        $item("#text4").text = itemData.score.toString();
        $item("#button1"). link = itemData. link;
        // Had to add a   ^ space here and ^ here to get around a forum warning
        // that I could not share links
    } );