Hi All,

Working on Outsystems 11 here, and am trying to make an app that gets data from APIs and just displays the data found basically. I have the api calls returning what they need, but the issue is I need data from two separate api calls made in my consume method into one table.

Now, I know that this is probably feasible in populating the data to an entity and joining it from there. I do not want to do this, because I don't know what kind of performance issues I'll be looking at down the road.

What I do want is for the API structures to be joined into a single structure so that I can display the API results in one table statelessly. I haven't found a way yet to neatly stitch together two structures into one.

I've tried a few different solutions and have scoured the forums to no avail. Here is where I am combining the data from both sources into one Structure:

Where each of the elements besides category come from one structure, and category comes from a different one. Since the for-each loop that I have this attached to does not iterate over CategoryResults, it just displays the last element for each record that I am creating.

Anyone have any ideas to accomplish what I am trying to do? Let me know if I need to clarify further.


Thanks,

- Cody

How are the results associated? Do they share some kind of unique ID in common?

Are these external APIs? That is, are they outside of your control?

More context on what kind of information you're getting from the APIs, and why you want to display in a single table might help in suggesting a better solution.

The APIs are for a video platform, and the data that I'm interested in from them are the name of the video, user behind the video, Urls corresponding to the video, id of the video, and the category.

These are external APIs and they do have a common Id, though it is not their PKs. The ReferenceId I have set as id is the common id for the videos between the two. I want to compare the two ID's and have each table correspond, but looping through two lists seems more difficult than I imagined.

I want to get them onto a table to have the user essentially select the data (with all of these fields present to make sure it is the right video) which will THEN be pushed into an entity as a 'request'. 

Solution

Hi Cody,

If there are no nested Lists, the ListAppendAll (instead of a For Each + ListAppend) is the best (and fastest) way to go. However, if, like in your case, there are nested lists, you need to For Each on the outer list (like you already do), and then ListAppendAll (+ mapping) the inner List (unless that has a nested list as well, etc.).

Since that latter ListAppendAll needs the right target, make sure to either use an intermediate Local Variable for the mapping (via an Assign) + ListAppendAll, then ListAppend that to the output List, or alternatively, ListAppend to the output List without an intermediate Local Variable, and use List indexing to get the last element for the ListAppendAll (something like OutputList[OutputList.Length-1]).

Solution

Kilian Hekhuis wrote:

Hi Cody,

If there are no nested Lists, the ListAppendAll (instead of a For Each + ListAppend) is the best (and fastest) way to go. However, if, like in your case, there are nested lists, you need to For Each on the outer list (like you already do), and then ListAppendAll (+ mapping) the inner List (unless that has a nested list as well, etc.).

Since that latter ListAppendAll needs the right target, make sure to either use an intermediate Local Variable for the mapping (via an Assign) + ListAppendAll, then ListAppend that to the output List, or alternatively, ListAppend to the output List without an intermediate Local Variable, and use List indexing to get the last element for the ListAppendAll (something like OutputList[OutputList.Length-1]).


This got me one step closer, the results I'm getting back are the initial list items but underneath are the category list items. You mentioned using list indexing but as I have currently in my initial list, the ID is set to NullIdentifier(), effectively making all the ID's 0. It might be easier to see how I have this set up rather than trying to describe it though:

Where CategoryResults and GetMediaList are the endpoints for their respective APIs.

I was thinking it might be easiest to have an id start at 0 and increment like a traditional for loop (for(i=0;i<len;i++)) and have the ListAppendAll reference that. How do I do something like that?

Cody Zehner wrote:

Kilian Hekhuis wrote:

Hi Cody,

If there are no nested Lists, the ListAppendAll (instead of a For Each + ListAppend) is the best (and fastest) way to go. However, if, like in your case, there are nested lists, you need to For Each on the outer list (like you already do), and then ListAppendAll (+ mapping) the inner List (unless that has a nested list as well, etc.).

Since that latter ListAppendAll needs the right target, make sure to either use an intermediate Local Variable for the mapping (via an Assign) + ListAppendAll, then ListAppend that to the output List, or alternatively, ListAppend to the output List without an intermediate Local Variable, and use List indexing to get the last element for the ListAppendAll (something like OutputList[OutputList.Length-1]).


This got me one step closer, the results I'm getting back are the initial list items but underneath are the category list items. You mentioned using list indexing but as I have currently in my initial list, the ID is set to NullIdentifier(), effectively making all the ID's 0. It might be easier to see how I have this set up rather than trying to describe it though:

Where CategoryResults and GetMediaList are the endpoints for their respective APIs.

I was thinking it might be easiest to have an id start at 0 and increment like a traditional for loop (for(i=0;i<len;i++)) and have the ListAppendAll reference that. How do I do something like that?

@Kilian Thank you for the suggestion. I misread your proposal and was not aware of the ability to iterate through lists in a much more conventional way than I had originally thought. I ended up taking the intermediary variable that I had created, and iterating it through the original for each's CurrentRowNumber (lit. CategoryFullIds[MediaTable.List.CurrentRowNumber]) This gave me the correct matching that I was looking for. Thank you so much, this was causing a major headache!

Hi Cody,

Great to hear you got it solved! Hapy coding :).