Help looping thru array with dynamic variable - issue with Promise

My use-case: using each SKU in my SQL database, I will compare its respective price with the current, realtime price retrieved using API. Later on, I will compare these prices and overwrite the price in my DB with the realtime price.

Query
This is from another Retool post about looping through arrays. My goal: retrieve the first SKU from the table and store it in dynamicSKU, pass it into getProducts (see below), and store the price retrieved from getProducts as a new variable (see comparePrices below). I will then compare the price from the SKU in the table with the price from getProducts. If there's a change (+/-) from the price in my database, I will overwrite the price in my database (I haven't made it this far yet - I'm still trying to get to the point of comparing prices).

This query hasn't really been working. In fact, it crashes my app every time I run it. Everything else seems to be working so far. Question #1: how can I amend this loop to meet the above need?

const bridalArray = await getAllBridalDB.trigger({});
//console.log(bridalArray)
const bridalArraySKUs = bridalArray.Sku

const query = getProducts

const promises = bridalArraySKUs.map((Sku) => {
  return query.trigger({
    additionalScope: {
      dynamicSKU: Sku
    }
  });
});

return Promise.all(promises);

getAllBridalDB
Simply imports SQL database into table. Each row has a unique SKU (not pictured)

Example of SQL data in table:

getProducts

comparePrices
I'm working with an array of nested objects. This script logs the price as a decimal. It should work for every SKU as the JSON structure doesn't change.

If I simply type in a SKU in the value of getProducts, compareProducts logs the price successfully. I will need this to be dynamic in production (hence {{dynamicSKU}}).

Question #2: how can I dynamically store this decimal to later compare with my DB price? I'd probably run the comparison in real-time in this script.

//Passes thru every object thru price
let values = Object.values(getProducts.data.Products[0].Price)
//use values[0] because values [1] is the currency denomination as a string (which is not needed)
let currentPrice = values[0] //current price of given SKU as a decimal
console.log(currentPrice) //result: 1610.93

TL;DR:

  1. Query: run loop to pass each SKU from getAllBridalDB as {{dynamicSKU}} in getProducts API call.
  2. comparePrices: assign price from JSON retrieved in {{dynamicSKU}} API call as a dynamic variable
  3. (Later use case): compare price from getAllBridalDB to price from comparePrices.
    3a. Update DB price as needed.

Hello! Welcome :slight_smile:

First question, is there a reason you're triggering bridalArray first instead of just accessing its data like:

const bridalArraySKUs = getAllBridalDB.data.Sku
const query = getProducts
const promises = bridalArraySKUs.map((Sku) => { return query.trigger({ additionalScope: { dynamicSKU: Sku } }); }); 
return Promise.all(promises)

And just to double check, what does your getAllBridalDB.data.Sku look like? Is it an array of single Sku items (e.g. ['123', '234', ...])?

Second question, when the above query works, it returns all the data from every query run! You can then access that data wherever you need to in Retool :slight_smile: Is that what you're looking for or did I totally miss the point of your question?

I'll test out your code later today! To answer your questions:

SQL data as a table:

image

const bridalArray = await getAllBridalDB.trigger({});
console.log(bridalArray) //Response: {Id: Object, Sku: Object, Description: Object, ShortDescription: Object, GroupDescription: Object…}
const bridalArraySKUs = bridalArray.Sku
console.log(bridalArraySKUs) //Response: {0: "60284:207117:P", 1: "60181:207408:P", 2: "60188:207417:P", 3: "60286:207121:P", 4: "60238:207132:P"…}

It sounds like it! I'll let you know later today :slight_smile: Thanks! One other question: Can you explain-like-I'm-5 what

const promises = ....

does in your code? I'm still struggling to wrap my head around the concept of promises.

Yup, your code worked just fine! This is what I ended up using:

//const bridalArraySKUs = getAllBridalDB.data.Sku;
const bridalArraySKUs = ['60284:207117:P','60181:207408:P','60188:207417:P'] //for testing purposes, provides only 3 SKUs
const query = getProducts;
const promises = bridalArraySKUs.map((Sku) => { return query.trigger({
  additionalScope: {
    dynamicSKU: Sku 
  } 
}); }); 
return Promise.all(promises);

Result:
image

Awesome, so happy to hear the code is working for you!

In my code, const promises= is just a variable name. It could be const butterflies= if we wanted.

The real magic happens at the end with Promise.all() is a Promise method that accepts a list of promises, goes through each of them, waits for everything inside to finish (which is all our query triggers in this case) and returns it all inside an array.

This description is much better than mine haha:
https://dmitripavlutin.com/promise-all/

Let me know if you have any questions at all!