ListView index in s3 integration

Hi, I'm try to retrieve from s3 a file using the [i] key from a listView component.

For example, I've a listView component with n rows. In the listView i'm able to retrieve the correct data with

query.data.invoice_number[i]

If in the s3 operation options I put

{
Key: {{query.data.invoice_number[i] + '.pdf'}},
Expires: 600
}

it returns "undefined.pdf".

Using [0] it works properly, but obviously if the number of rows is > 1, only the first item as the correct data.

Can you share a full screenshot of your s3 query? Are you looping through query.data to then have access to i?

@Jay No, I simply do the same I do in the listView component

image

Hey @number15,

Happy to help take a look here. Could you share a full screenshot of where you're putting this object in your screenshot? Is this a query, component, or a JS transformer? Could you also share what you're trying to do with this data? Having the answer to these questions will give us a better idea of what you're working with. :slightly_smiling_face:

@Kenny ok, let me try to give you more details.

This is the listview component, with inside multiple containers based on the number of store orders.


To get the correct invoice number, that is different per store order, I use:

{{ store_orders_by_order_id.data.invoice_number[i] }}

and it's working properly.
store_orders_by_order_id is a MySQL query.

What I'm trying to do now is to create the signed url link to the pdf file on S3.
So I've been able to create the integration with S3.

The problem is how to get the correct invoice for each store order.
The "magic" [i] seems not working.
With [0] it works, but I get the same link also for the second store order (it's clear to me why, so this just to say that the S3 connection is working properly).

I hope it's clearer now :slightly_smiling_face:

SUPER helpful, thanks so much for sharing that! It sounds like you're looking to run the query for multiple invoice_number and run this query multiple times. To do this, you can perform a loop to run this query for each invoice_number similar to what we have for Running a query for each row of a table (check out #4).

Keep me updated if that works for you @number15 !

@Kenny thank you for your suggestion, but I'm still having problem printing the correct link.

I've created query7:

var rows = store_orders_by_order_id.data.invoice_number;
function runQuery(i) {

  if (i >= rows.length) {
    console.log("Finished running all queries");
    return;
  }
  var invoice = rows[i];
  console.log("Running query for invoice", invoice);
  getInvoice.trigger({
    additionalScope: { invoice: invoice,
                     }, // This is where we override the `i` variable
    
    // You can use the argument to get the data with the onSuccess function
    onSuccess: function (data) {   
      runQuery(i + 1);
    },
  });
}
runQuery(0);

That the query runs for all the invoices.

Operation option in the getInvoice s3 query is set in this way:

{
Key:  {{invoice + '.pdf'}},
Expires: 600
}

The problem is how to print the correct invoice in the listView, sincegetInvoice.data.signedUrl returns always the last one.

@number15, one option here would be to create a Success event handler for your query to save the signed-url using temporary state. An example would be to use an array and push the newly created signed-url into the temporary state. You'll then have access to {{state1.value}} (your temporary state) to place into your listview component using {{state1.value[i]}}.

@Kenny I'm not able to let it works :frowning:

I think that the problem is the temporary state that is overwritten with the last value.

Which should be the default value of the temporary state?

or {}

How I can append the signedUrls to the temporary state?

With setValue it overwrites the temporary state with the last value.
I understood I need to use the SetIn but i'm having trouble setting the correct key.

I set added the events on success for the S3 query and with the notification I see that is generating the correct urls:

list_invoice_signedUrl is the temporary state.

Hey @number15,

You're almost there! Just need to make a few tweaks. You can start with your temporary state as an array or object, up to you how you want to organize your data :upside_down_face:.

In order to append data and not override it using an array, you'll need to use a JS query and use the temporary state's setValue() function.

1) Start with an array for your temporary state

2) Create a JS query to set temporary state's value to append new signedUrls:

  • Make sure your query's data for your signedUrl is returned as an array
  • Set your temporary state to the result of: concatenating your temporary state's value + signedUrl data
let tempState = state1.value,
    newData = query10.value,
    result = tempState.concat(newData);

state1.setValue(result)

3) Set an on-Success for your query that's grabbing the signedUrl to trigger the query you made in step #2 every time the query has completed running.

Hope this helps!