Right way to set argument between two async functions

in a template events function I have to do the following steps in order to get a ranked list of results:

1.call the asynchronous function userTaxonomyProducts, that gives as a result the object Taxonomyproducts
2. use and handle the object Taxonomyproducts to conclude in a new object Taxonomyproducts_attributes that will be used in step 3 as an argument to the second async function call search_for_products
3. call the async function search_for_products

with the use of promises I can get the results of steps 1 and 3 but I am not sure how I should handle the step 2 should I create another async function and call it between steps 1 and 3 or is there an easiest way that I can handle the result of the async function.
My code looks like below:

Template.product_selection.events({
‘click #show_products’: async function(event,instance) {
event.preventDefault();
instance.state.set(‘show_products’, true);

  ......
  
  promise=new Promise((resolve, reject)=>{
    userTaxonomyProducts(params1,(Taxonomyproducts) =>{

        resolve(Taxonomyproducts);

    })

    })
     promise_ranked=new Promise((resolve, reject)=>{
        search_for_products(params2,Taxonomyproducts_attributes,(Products) =>{
           
            resolve(Products);
        })

        })
  //step 1
    const Taxonomyproducts=await promise
    console.log("Taxonomyproducts",Taxonomyproducts )
  //step 2 
    INGR_1=[]
    INGR_2=[]
    INGR_3=[]
    INGR_4=[]
    for (i=0;i++;i<Taxonomyproducts.length){
        const Taxonomyproducts_attributes={
            "INGR_1":INGR_1.push(Taxonomyproducts[0].Offerings[0]),
            "INGR_2":INGR_2.push(Taxonomyproducts[0].Offerings[1]),
            "INGR_3":INGR_3.push(Taxonomyproducts[0].Offerings[2]),
            "INGR_4":INGR_4.push(Taxonomyproducts[0].Offerings[3])
        }
        console.log("Taxonomyproducts_attributes",Taxonomyproducts_attributes)
    }

//step 3
const rankedProducts=await promise_ranked
console.log(“rankedProducts”,rankedProducts)
Session.set(“recommendedProducts”,rankedProducts);

}})

and the problem is that step 2 gets undefined so I cannot further use it to call the step 3 as I should

Promises start executing as soon as they are created, so you’ve created a race condition hoping the first request will finish before the second.

await the first promise before starting the second, since it depends on the result of the first

but I do wait for the first promise as shown above.
I assume though I should write step 2

 //step 2 
    INGR_1=[]
    INGR_2=[]
    INGR_3=[]
    INGR_4=[]
    for (i=0;i++;i<Taxonomyproducts.length){
        const Taxonomyproducts_attributes={
            "INGR_1":INGR_1.push(Taxonomyproducts[0].Offerings[0]),
            "INGR_2":INGR_2.push(Taxonomyproducts[0].Offerings[1]),
            "INGR_3":INGR_3.push(Taxonomyproducts[0].Offerings[2]),
            "INGR_4":INGR_4.push(Taxonomyproducts[0].Offerings[3])
        }
        console.log("Taxonomyproducts_attributes",Taxonomyproducts_attributes)
    }

(calculate the Taxonomyproducts_attributes object to be used in last step 3 async function) as a promise as well, right?

Yes, but

Which means the second step is already running before you wait for the result of the first.
You need to create the promise_ranked promise after the code that creates Taxonomyproducts_attributes

1 Like