Video: Part 2: Mastering Loops in IO | Duration: 3620s | Summary: Part 2: Mastering Loops in IO | Chapters: Advanced Looping Concepts (4s), One-to-Many Data Processing (473.19s), Processing Records Through Mapping (757.94s), Exploring Data Flows (1215.25s), Pagination and Presave (1307.1749s), Scripted Looping Techniques (1451.465s), One-to-Many Step Demonstration (1620.045s), Mapping Shopify Data (1835.505s), Error Handling Options (2203.6748s), Error Handling Techniques (3108.055s), Q&A and Conclusion (3370.015s)
Transcript for "Part 2: Mastering Loops in IO": Welcome, everyone. Thanks for joining us for part two of our Mastering a Looping Series. I'm Kelly Eiser, a senior solutions consultant at Celigo, and I'm joined today by Jonathan Yiller, our lead technical adoption specialist. Today, we're diving deep into advanced looping concepts within integrator.io. Let's take a look at this sample flow. Whether it's an import or a lookup, each step in integrator.io is composed of hook, mappers, and filters. You've probably seen these in the UI. But today, we'll unpack what's happening behind the scenes as the data is being passed through each of these options, As these features are what really gives you the ability to make sure that your data is being processed and handled correctly in order to support your specific use case. Here's how the looping logic unfolds within integrator.io. We start with the full dataset, say 80 records, and then pass each one sequentially through steps of the integration. Our starting point in today's example, is is the step you see here, getting orders from the Shopify QL, step. This is where we'll retrieve our first dataset. From this export step, you have various options for handling your outgoing data. You can apply scheduled override, transformation to restructure your data, or an output filter to allow only data that matches that specific criteria to be passed through into your pages of data and, moved on within the integration. So for today's example, we're gonna take those 80 records, and we're gonna use an output filter to start to show you how it's gonna pass through there. Here's an example of defining an output filter. You can set up rules like using and or or, to precisely control which records proceed and get passed through the subsequent steps. So in this case, the first thing I did here, and you can see up here at the top, giving you an example where we're gonna take those 80 records that were generated from our previous step. What Integrator IO is going to do is we're gonna take those records, and we're gonna start to pass those individually one record at a time through that, output filter so that each record will have the logic applied to it. So here you can see Integrator IO is already gonna be looping through those pages of data or or those records that were pulled out of your step. From once that filter logic has been applied, what Integrator IO will do is it's going to then take those records, filter out the records that do not meet the criteria and such. And from there, what it will do is start to split those, that dataset into pages of records. Now those pages of records by default within Integrator IO, are set to 20. You know, you do have the ability to modify that as necessary. But by default, each page of data that is generated contains 20 records, and there is a five meg page size limit on that page of data. But you can see here as we start to generate those pages of data, your first 20 records would be created as a page of data. And what we do is when we create that, we also name it data. So that is held within a data array is what we do there. So you'll have your first page of data, your second page of data, and then it's gonna generate your third page of data here in this example. Now that you have those pages of data, let's take a look and see how Integrator IO will pass that data through a pre safe hook. On the left, you can see that the function input, which represents the data coming into your script again, just to reiterate, there are three pages of data that we passed into the script. I will pass the entire dataset into the script for the logic to be applied. So you can see here, it'll take the entire data array, which you can see is highlighted here. So you can see data is shown here. So what Integrator IO is gonna do is take the first page of records, the entire data element, and it's gonna pass it into that script. So you can see here, it's gonna pass it in. Within there, you can see, you know, your first page of 20 records will be, included there. Once that data has been processed, it's gonna go and move that over to the, output. So it's gonna take the entire dataset. It's gonna apply your logic to the first data and move it over your output. It will then take your second page of data, hand that to the script as your input, generate that, process that out, then it'll take your third page, pass it to the script. All your records pass it in and move that over. Once you have that data, you can see, again, it'll go through your output function. So, again, it's still keeping it in that entire data element there. Once you have those, what Integrator is gonna do is it will take that and then take the data and rebuild that into your page of records now. So, again, you'll do it your first page of records for your 20. It'll have to take your second page of records there, generate those, and your third. So now you've got your pages of data again that have been applied or been ran through the script to have that logic applied. So now your dataset contains your modified data as defined by your script, and you now have that information setting there. Now that you have those pages of data that had been ran through your output filter, it's been handed through the, job the presave page script here. You can see there. Now what it's going to do is we're gonna pass that to the next step within your integration. So now let's analyze and see how the data's processed here and how we loop through it. So to begin with, you're gonna see here, you're gonna take your first page of data, and we're gonna look at our our step here. What Integrator IO is gonna do is it's gonna take that data. Now because you're going to be processing into this step, Integrator IO is automatically going to loop through that data array here, and it's gonna start handing all your records, r one to r 20. It's gonna hand those into each of those steps there. So it's gonna take your first page of records, start processing those, pass those into your, step. It's gonna take your second page of data, go into the data loop, hand those into that step, each record, one record at a time there. So 21 through 40. It'll then take your third page of data, pass that into the step each record of time, 41 through 60. With a single record, when it starts moving through those steps like the transformation, mappings, and API calls, let's start to look at what's inside of those loops, and such. And this is where we can step through the parent child relationship for that one to many. Again, as I just showed, we're gonna take that entire single record from that data, and that's what's gonna start to be passed into the step to be processed. Let's zoom in on this single record as it's passed into the one to many import, and then you can see, that there's a line item array within this individual record. This array is key for the one to one for many scenarios because each element within that array will generate a separate record in that, step as we process through it. Another key thing to note is that with the one to many option, you can still access the parent level data, which is denoted by the underscore parent within the JSON. So as we move that through each subsequent step here, you'll the Integrator IO will be working within this dataset because you're doing a one to many, but you'll still have access to that parent level data. Let's take a quick look at configuring the one to many steps. So as you pass that data in, when you configure the one to many, what you're going to do here is you're gonna name the step and set the connection as you typically do. The critical part here in in setting up this one to mini is clicking on that one to mini option and changing that to yes. Once you, change that to yes, what you're gonna see is Integrator IO is going to open up, and then you see this path to many options. On this path to many, what you'll wanna do in this example is we're gonna set that to line items. Now that this step has been configured to use the one to mini option, you'll be able to see that Integrator IO will automatically loop through the elements of that array. Look at the input filter here, for example. When you open this and view the input data, you can see that the record now contains the line or the information from that line item array. But you can also see here that you have that parent element. This is how you can tell that Integrator IO is passing each individual, element from that array into each step here to be analyzed. Now let's look at how Integrator IO is gonna pass that data into a one to mini presave hook here. So, again, like we were looking at before, you can see that as that data is being passed into this step, you're gonna have your, entire set of records from that page of data is gonna be passed in. But let's dig a bit deeper there and look at that. So here, you can see again your input function is showing you that that you're still working on that page of data here. So you have a page of data. You can see you have multiple steps there or you have multiple records there. But if you look at the individual records there now so if we just take one of these records, and highlight it, you can see that inside of that data, it is at that one to many level. So you're actually looking at the line items here on that record. So you can see I've got the fields from my line items array. But here's that parent element, which tells me that it is at that one domain level, so the line item's there. So, now once Integrator IO goes through, your script is gonna run on the data given to it at that one to many line level. Then you can see here, it's gonna process through each of your records. It's then gonna take that entire dataset. And then, again, like we did before, it's gonna go back out here and re or regenerate your pages of data, wrapped in that data array there. Next, let's look at how Integrator IO is going to process those records through the mapping step of this. Again, you've got your pages of data. So as we start to move those pages of data through the mapping, here is where you gotta understand again that what Integrator is gonna do is it's already going to loop through that data array here. So here's where you're gonna see. You'll be able to take your first well, what Integrator IO is gonna do is take your first page of data. It's gonna start taking those records from r one to r 20, pass it into the mapping stage. So then as you bill out your mapping, SKU to SKU, you know, title to title, whatever it may be, you're actually working on the elements there of that one to many records. So, like, your line items, you're able to use those. It's gonna take your next page of data, pass that into the mapping so that when that those records will be processed through in your destination, you know, you're working on that element. It'll take your third page of data, process that through. Again, just showing you that if you look at that input data, you can again tell that you are working at the, one to many data array element of line items by the existence of that parent, node there, which has your parent data, which you can still map to by doing underscore parent dot ID, underscore parent dot name, and such. So you still have access to that info if needed even though Integrator IO is, you know, passing each record in at that one to many level. Now that your records have been processed at that one to many level, next, let's take a look at how that data comes out of that step and is, passed into each additional step after that. So first, you'll see here that when you do a step like this, when you have additional data that is enriching your initial dataset, you need to set up a response mapping. So for an import, what you'll see here is you could go in, you configure the, response mapping. When that comes out, you'll see integrator.io will give you an object called underscore JSON. Well, that's going to contain whatever information, is per is returned from that API call there. So, for example, in this system, you'll see over here, underscore JSON contains the element called SKU. Right? Now once that comes out, you have the JSON element, you have to give it a name. So that name, what that's going to do is that's gonna basically give you that representation inside of your JSON object, for your response data. So what you'll see here is as it comes out of that response mapping, you can then pass that data to the next step. So in this case, we set up a post response map here. So you'll see here as I open up my script editor, you can see, I have a post response map element here. So that's where that data is gonna come out of there, go into your hook for your post response map. Now key thing to note here and to understand how this is getting passed is now, if you'll notice, what you'll see is in the post response map, we're out of that one to mini loop. Now when you look at this data record, you're back at that entire record. So here is that top level information. Here is now your line item. So you can see here, we've got that info. But, also, what I just highlighted here, if you open this up, is there is that response map information. Right? So you can see that that was added into your one to many element there. Right? And it is included inside of that line item. So you now have your response map that was added into your individual record that was passed through, which is then contained inside of that array element, which is all now inside of that parent record. So as it comes out of your one to mini, your response map comes through, adds that response map data into the one to mini, which now as it's outside of that step there, you're now working at the entire record level again. So now what Integrator IO is gonna do is go through those records and now rebuild your page of data. So now I'm back to my page one of records, page two, page three, and such. So now that you've got your page of records coming out of here, where that's going to now come in is as you go to the next step in your flow, Integrator IO is gonna start the process again with your next integration step within your flow. So it's now gonna take that entire page of records. It's gonna start processing those, pass it into your next step, and process it into the next step as well. And then repeat this all the same concepts we just went through here and how Integrator handles those records for your input filter, your hooks, and mappings, and such. So thank you everybody. I, again, I appreciate your time, and have a great day. This is Yanton. Thanks, Kelly, for that presentation. And now I wanna share, I wanna share my screen and kind of go through this this flow that Kelly was just showing. You'll notice we we we kinda we as we were preparing for this, we realized it was a lot nicer. Kelly is amazing, Paula. I agree. We it we realized it was actually a lot nicer to illustrate a lot screenshots. So we took a lot of screenshots. Adam, good colleague, you noticed that, when we when we made the screenshots, we just had one item per per order, which is not probably the best presentation of one to many steps. So I actually added some, records since then with multiple lines. But what I wanna do now is is share my screen. We can we can look at this flow. It's it's the same flow that Kelly was showing in the presentation. And let's see here. I'm gonna share this screen. Yeah. And and that that's right, Henry. Kind of the goal is there's a lot of stuff that was easier to to show with screenshots and, you know, some additional markings and illustrations on them, but we did not wanna miss this the opportunity to just look at the flow. Feel free to throw questions at me as I go along. So oh, will do. Is that better, Omar? Oh, Omkar. Sorry. Does that look is that zoomed in enough? I can also move the smaller monitor if that would be easier to see. Okay. So I wanna start I just we'll just kinda step into the flows and look at the data as we have it in each place. So first, we have the export the export set, but, I built this with just a a pretty generic GraphQL call to get, get order data out of out of Shopify. And this is a it's a sample Shopify store, so you'll notice there's not really that many orders and they're all, like, Johnny at fake email, but it gets kinda gets the point across. So we get here we get an this is the pagination from the source system. So you can see on the export, we call it page of records, and we indicate that each one is a record. So the, you know, first record is this order 1001. And after that, we have the second record is, order 1002. From here, I wanted to show this presave, book. So this is a a presave on the initial export. If we had and I apologize. I don't I don't have a output filter here, but I think in the Kelly was showing what it would look like if there were an output filter. Let's let's just make one real quick. Let's say, the order ID does not equal 99999. So let's say we exported a 100 records and one of them had that ID, we would then end up with 99 records. So those would be split up into pages. In this example, under advanced, I think I set it to page size of 10. Let's set it just for fun. We'll set it to page size of five. So now, really, I have 10 records, so I should have I should do two pages of five. This filter won't actually filter anything out. Oh, actually, why don't we filter out yeah. Whatever. I'm just gonna do a little bit. So I wanna look at the presave, the presave hook. The presave hook is after our initial output filter, was run. We have this array of data. In the preview data, I only, integrator just shows us the first record, but you could imagine that we we could have five different orders here. Get so let's set the page to five. And I wanna look at what the structure of the data looks like. So first of all, within any scripted steps, in Integrator IO, options is our global variable for everything you see here in in the middle, which is the function input. So anything that you want from the middle screen here, lives inside options. In this case, if I wanted to loop through the page of records, the the records all live in the data array. So, I wanna show you a few different a few different approaches for looping scripted looping. So this is my favorite. I I write a loop like this every single day that I might work. My favorite way to define a a loop is, I say, four. I define a variable, that that's what I would call the the thing with that I'm looping through. So in this case, I'm looping through records. I'm gonna call each one record. So I'm saying, let record that's I'm just defining, but that's what each individual thing will be. And what am I looping in? So I say of and then options dot data. That means I'm in options, which is this thing in the middle, and data is this array. That options there's a question here. Can we call it something other than options? And the the short answer is no. That this is a global variable. So at the beginning of the function, we would always we would always call this options. But if within your script function, you wanted to refer to it as something else, like if you what the but the question said a b c. So we could we could define a new rare variable that we call a, b, c and have it equal options. And from here on in the in our script, we could reference a b c, and it would it would hold the things that are within options. So you you could do that. I hope that answers the question. Adam, JavaScript is in is in scope for this demonstration because if you do wanna talk about thinking through this, but, yes, I I don't wanna do too too deep of a dive on a a lesson in Java script. So I'd I'd mostly, I wanna show what the what the looping structure looks like. So fair point. Okay. So, yeah, here I could define okay. Let's let's call each thing within data. We're gonna call it record and within options data. And then this is my script. I'm I'm doing stuff with it. I like coincidentally since I fetch the data from Shopify using GraphQL. I find that when I ever work with data from GraphQL, I like I like to clean it up a little bit. So that's kinda what I'm doing in here, and I will not get into the everything else that I'm doing in the script. But the the output again, I'm gonna have, an output of of, orders. So each each object here, well, that's what the thing called record for, but we know that we're working with sales orders, so that's what these are. And I can see that the data is a little bit cleaned up, which was my goal with the script. Okay. I'm going to get out of this step. And now let's talk about our next step of the flow. This is you'll notice, we built a couple of examples of one to many steps. This one is an import. This one, is a lookup. They don't actually do anything as they're really all kind of bogus steps just for the demo, just to look at the data structure. But let's say for some reason, for every line item on an order, we needed to import something somewhere. So that's what this would look like. Within the import step here, I I define this as one to many, and I said the path to many is line items, which was an array in my in my record. And now I wanna Kelly showed this in the in the slide deck, but I will I'll reiterate. I I kinda wanna show the different steps. What's what's within the one to many and when do we step out of the one to many? So for example, I defined this box as one to many. The input filter here, this is already in the one to many. So you can see we're in record, but the we can see the the order level stuff is inside this parent object. And the other fields that that we interact with are on the line level. So this we're within the the one to many loop here already. Cool. Well, I would also enjoy that. I I would like yeah. It might be good to just do just a generic session about working with Shopify GraphQL since a lot of us have to spend a lot of time there right now. Yeah. Will, was asking about just saying it would be nice to have a session one day to talk about cleaning up, data from from, from Shopify. Okay. So, yeah, here we are. We can see where are the in the one to many on this filter step. And there's a few things we can add to to a flow step. Typically, on an import step, an input filter is common. A mapping step is common. So let's look at the mapping step. Again, in the mapping step, we can see we're we're inside that. Not only we're inside an order, but we're inside a specific line item from our first order. If we wanted any of the data from the order header fields, we would find that data here in parent. So here we can see the order that we're in is this, and then we could we could map, you know, our mapping natively will go on the on the line item fields. But if for some reason we wanted to also add to the mapping the, you know, order number, we need to go to the parent and we can fetch the Shopify calls it the name, but it's the order number. So we could add that to our mapping here. In some cases, we we would need a scripted step maybe to add some logic before before we do the mapping on an import step. If we are on a one to many and we click into the pre map hook, you'll notice I'm using the same script file for for all of the example, functions here. This is some I I usually like to do this unless I have unless I'm working with a flow that there is one scripted step where the script is really long. I I like having a single script file for all of my functions on a specific, on a specific flow. Makes it easy to keep track of and and, especially for let's say, you have you're using, sandbox version or production version or maybe another branch of of the version of the of the flow or the integration, kinda keeps your script files from going up too out of control if you if you could keep it to one script file per flow. But here's our our premap flow. Again, we can see the the premap function. It first, we we define the function and we we define which function is gonna run, and it refers to options. Again, options refers to everything here in the middle. And you can see here we again, we are inside the record and we're inside a line item of the record. And there's a different, different approach to looping within the with for this example. If you're ever working, any of you that have worked with our JavaScript hooks, you're probably familiar that we have some prebuilt function stubs for for these types of functions. So for example, if I say, oh, I wanna add a premap stub, it actually this is the only one that that it includes a loop loop function within it. So I'll delete this one. But let's say here, this is an just another method to loop through the funk through the the data that we're working with. So if I wanted, this would be absolutely crazy, but what if even inside my line item, I had another array for inventory details? If I could spell, that'd be cool. But, theoretically, I could I could have a nested array within this even though I'm this far end. And let's say I wanted to, wanted to loop through these records and then take some action on on this other array or maybe for every for every item here, I wanted to add. So here, the default it's it's calling the data, d, but it's the default thing that comes with a stub. So let's say I wanna say d dot item field, and we'll give it a value, new call it that. So that would add that that would add that to each one of our items. I'll leave that there because that might be fun to look at, later. Logan has a question, and I'm sorry if I missed some questions along the way. I'm easily distracted by the comments, so I'm trying to look at my screen more. Logan is asking a great question about, ignoring certain errors. And if I have some time at the end towards the end of the session, I I do wanna show you how to do that, Logan, because, yes, you can do that with, with some scripted steps. Okay. I'm going to skip the post submit hook, and I'll circle back to it later. Okay. Usually, after after we do an import step, we we might get a response. Maybe we get an ID for each record that we imported somewhere or or some some value that we need. So, typically, after an import step, if it's not the final step of the flow, we would have some response mapping. Here, we we have the the response from the system we called. I'm really interested in this, SKU field in the data. So I'm I'm just but for now, I'm just saying, okay. Just give me the whole response. And I'm saying that it's giving the import import response JSON. If we preview this, you can see the record here. We're still we're still inside that one too many on the line item. And I'm gonna go next. This is another thing that's a common a common place for a script to live is maybe after we got the response from this step, then we wanna apply some scripted logic to the flow. Many of you would have noticed that there is a a really unlikely number of scripts in this example. I I hope nobody ever has a flow with that many scripts in it, but with that many script books. But just for as the example to kind of show what the data looks like at each step. And I wanna point this out. This is where this is an interesting one because now you'll see we're outside of that one to many. So once we get to the post response map data, now we're outside of the one to many. So, again, the we we're in this post response map function. Again, we reference options, which is everything here in the middle. And from options, we're interested in the the array, the data array that here is called post response map data. And, within it, we can see our array of line items and that this is the thing that we were doing the one to many on. And here we can see on each line, the first order only has one line on it, but we could see on each line, we would have that import response JSON that we from our post response map that we did. Okay. I'm gonna I didn't make any changes here, so I'm just gonna close this. Did I make changes here? I don't think so. Okay. Let's, we'll circle back to this post submit, function. This is, one of the less often used functions. But I did wanna show you this funny thing about the post submit. This really you can see that the data that we're working with here on the the response data, that's response from our import step. It actually doesn't contain any of our data from upstream in the flow. So in the post submit hook, we're really just working with the data from, from the response of this current step. If for some re it's it's the least probably the least common place to interact with data in in our flows, but just so you know, it is possible. For some reason, if you wanted to let's say if this was a GraphQL step and you wanted to, to flatten it like we did in the in the presave step in the first, in the first example, this would be the right place to do that. Alright. Here we did we have a one to many lookup. It is extremely similar to the one to many import. So I'll step in here. We have we set it to one to many online items. The input filter, you can see we're already in the one to many. I used, presave. Again, the presave hook that so that's the same the same as the the post submit on the a port. That would let us kinda flatten the response from, this step before it gets before it gets to the results mapping step. And if we preview the results mapping, you can see this is on the item level. So we're still we're within the the one to many in the results mapping. And, again, if we go to post response, you'll see I have a separate function here for post response from our lookup. It references options. Now I want to show you my least favorite way to loop through something. I showed you my favorite way on our presave, which is for let record of options dot data. I am a big fan of explicit variable names, so we know what we're working with. But a lot of people, especially in some cases, this is this is necessary. We we wanna know the index that we're iterating through. But also when you're new to JavaScript, this is kind of the the globally most well known way to write a loop in JavaScript. So I thought I would give it an honorable mention here because you are likely to see loops if you're looking through through scripts that somebody else built or you might have written scripts this way. So this is just a common thing for for you all to be aware of. So let's say we want to iterate through options dot, post response data. Another another way, the most common way in in JavaScript to define a loop is we we define an index. I is the globally most popular variable for an index. So we define an index and we we give it the value of zero. And then we say, while our index is smaller than the length of our array, we'll keep iterating through this loop. And each time we'll add the value plus plus, meaning we're adding the value of one to our index. And just because I can't stand working with indexes, you'll see that the very first thing I do within the loop is giving the the the variable, giving an explicit name to our variable. And I'm saying, alright. For each option, dot post response at the index I, I'm calling that a record, which really this whole long thing gave us this short thing. But good to be aware, but that's that's a thing. And here, I'm just defining, record dot new value just just for fun to kind of add add a value to our data, or new field new value. Okay. Sorry. I'm talking a lot longer than I expected to. I'll try to cover a couple more things. The the next thing that you might encounter is branching. When we encounter branching again, for the example that I made kind of a bogus scenario. So, my scenario is that some orders are from point of sale, some orders are from, online. The or the online orders would have an email address, and point of sale orders would not have an email address. And, theoretically, our import step at the end would be different. So here, my branching asks this question, does the order have an email address? If the email is not empty, it goes to a branch called has email. If the email is empty, goes to a branch called no email. And you can see I have different import steps for each scenario. Now the, Omkar is asking about the lookup cache functionality. Kevin, Shah, and I were talking about it earlier this week. We are also really excited to have a session about that. So, that that will definitely be the that's on the agenda. So I I wanted to talk about one to many or looping with branching. And the reality is that the our branching logic always is at the parent level. So, if our page of records, is in this example, it's the sales orders, our branching will be on the on the sales order level, not on the line items level. That's important to know. If ever you're building a flow or want to build a flow where you wanna have branching that's actually on the line level, you might wanna consider changing the structure of your data right after your export step so the each record is one of the line items, and that will allow you to to branch on the line items. But the the behavior of the branching in our flows is on the parent record. And that's it. That's everything I wanted to show you. And, Alexi, I think would now be a good time to kinda open it up for q and a? I don't know if Kevin or anybody wants to go go on stage with me here. We we do have couple of questions, for q and a, Anton. Great. I think so. One question we have is from even before that, Yanton, do you have some time to show, to respond to Logan question regarding I believe, it was from, Logan regarding, like, how to, regarding the error. Right? Error, please, in the question. Yeah. Any way to ignore certain errors? Yes. That was a great question. Let me share my screen again. Okay. Here's my screen. So there are a couple of things we can do. One is, if you just wanna ignore, for example, all errors from a specific step. Let's say you have a lookup, and we run into this sometimes where some systems, when, you try to look up in some additional piece of information, And if you look up and the system doesn't find the record, instead of giving you an empty response, it gives you an error. So that would be a scenario where you might wanna say, you know what? From this step, I just wanna ignore all errors from this step. So one thing you could do is, we can, select the error handling option here, and we can say proceed regardless. Like, we we just don't care about errors from this step. We just always move move on to the next thing, and we have some scripted logic to do if that piece of information is missing at a later step. So that's one option. Well, actually, I'll I'll save it here just so we can see what it looks like. So you'll see this, error handling step here. The default behavior is that it it would error out and stop right there. The other option is that, not in every script. And, again, the since the purpose of this, presentation is not too too much of a deep dive into in the JavaScript. I won't go too too deep into, every, place that we can add a script to. But I'll I will show it here actually the in the presave. It's really easy to see. So remember, we have this thing called options, which is the function input. And in a lot of places, we can actually see the array of errors. So if an error occurred on the step, we would actually see the error in this array, and you could write a loop. So I'll give an example here. I could say for let error, of errors, or options dot errors. And then, you know, the I'm just gonna you know, the error object might be, like, code 500. I don't know what I I can't remember off the top of my head exactly what they look like. You know, some some message, and I can't remember off the top exactly what what are the structure of the error might look like. But let's say you expect you're expecting, that sometimes you're gonna get an error from some step. You're gonna have an array of errors. So I'm gonna say, okay. For my array of errors, I'm gonna I'm going to to iterate through the errors, and I'm gonna say, if error dot message equals this specific message, then I wanna do something with it. Actually, remember how I was all, like, talking about how I don't like using indexes? This is an example of somewhere where I might use an index. So, in fact, I sometimes if I wanna look through errors and I might wanna remove one of the errors from my array, I might actually, write a loop instead of this instead of this for loop. I might actually write a loop where I say, okay. For, let's define let index equals zero where, index is smaller than options dot pairs, dot length, and, index plus plus. And then I would say, I'll define error. Error equals this at the position of the index. And then I'll see okay. If this error message means it's something not important, then I might, use a splice, which is a a JavaScript command for removing, an indexed record from an array. So I would use it here. I would use a splice command, and I would reference the index. So this is actually an example of how to remove errors and when an index loop is valuable. So so, I'm gonna move on to the next questions here now, but I hope hopefully, that was a a bit of a intro on the topic. Yeah. Thank you, Yanton. So we have a couple of questions. One is from Yanton, and he's asking if the flow process sequentially, one record at a time, are the pages formed after each step? Yeah. So I'm not totally sure I understand the question of if the flow process sequentially. But if I if the quest if you mean to ask what happens if each time the flow runs, it's really only handling one record, the structure would be the same. We would still see we'd still see a page of data with the and data would be in a always be in an array. And within it, instead of seeing multiple records, we would just see one. So the data structure, whether you're processing a single record or multiple records, the the structures of everything Kelly showed and everything that I'm showing is gonna be consistent. You just might have, you know, pages of one record. I hope that answers the question. And then the question is from Omkar. He's asking, like, how to process if there are multiple line items per parent record? Yeah. Sorry. Adam called me out on this at the beginning of the session. Well well, there while Kelly was still presenting because my the first few orders in my in my sample environment only have one one item on them. But if we have if let's let's actually we'll change this. Let's find a more up to date. I'm just gonna grab this ID. Let's say we only wanna process a record that only this one record. And I'm just gonna run the flow. So it's just I'm just processing one record. So we'll see there's gonna be one page. Oh, pardon me. What did I do wrong here? Alright. Yeah. We'll see one page. We'll see nine records ignored and one success. And then we'll be able to see how it behaves at each step here. The it has three items. So three went through the the one to many import step. Three went through the one to many lookup location step. And, the order I picked was an order without email, so it went to to this step. You know what? It would have been good of me to turn on my log logger, then we could see what the record looks like here. Let me, let me run it again. Oh, how are we on time? Are we are we on time? I'm sorry. I was rambling too long. Okay. We we are on time, and probably maybe we can answer. Please feel free to reach out to me or Yanton or anyone, and more than happy to answer all the questions via, via email or anything that works. Great. Well, thanks, everyone. Sorry I blabbered on so long. I I hope I didn't miss too many questions here. But, yeah, please feel free to reach out if you if you wanna follow-up. If you have ideas or request for future sessions. We'd love to we'd love to get back to you. Thank you, everyone. Alright. Thanks. Have a great day.