Arcade For Loop & Attribute Updates on other Features

7067
6
Jump to solution
08-05-2020 01:47 PM
TL2
by
Occasional Contributor III

I am having trouble with for loops.  This example prints out the second item in the array.

var array = ["RC-22p", "RC-22e"];;

for(var c in array) {
    var invoice = array[c]
    
    }
    return invoice‍‍‍‍‍‍‍

The result is RC-22e.

I am trying to loop through an array, look up the corresponding globalid and update that related record.  When I run my code the first item in the array is completed, but it stops after the first one, it doesn't loop...  How can I get my for loop to loop when my return is updating another feature class?

var array = ["RC-22H", "RC-22I"];
var pipe = "";
var invoice = "";
var i = "";
var c = "";
//loop
for(var c in array) 
{
//lookup globalid based on item in array
    var pipe = FeatureSetByName($datastore,"SUDOECMS.DBO.doe_EAP_pipelineabandon");
    var invoice = filter(pipe, "invoice = '" + array[c] + "'");
    var i = first(invoice);
//if feature value is q_1, update the other record        
    if ($feature.q_x == 'q_1'){     
            return {
               "result": $feature.q_x,
                   'edit': [{
                       'className': 'SUDOECMS.DBO.doe_EAP_pipelineabandon',
                   'updates': [{
                       'globalID': i.GlobalID,
                       'attributes': {
                           'q_1': $feature.status,
                           'q_1comments' :  $feature.q_xcomments,
                           'q_1rank' :  $feature.q_xrank
                                          }
                                   }]
                            }]
                       }
}
//stops here but I want to repeat, it only updates the other record based on RC-22H, it does not update RC-22I.                ‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Xander Bakker

0 Kudos
1 Solution

Accepted Solutions
XanderBakker
Esri Esteemed Contributor

Hi TLongSUGF ,

I think it will be very difficult to provide working code without access to the data, but have a look at the  code below. I changed some variable name to make it a bit more understandable for me. Some observations:

  • I removed some redundant declarations from the start of the expression
  • On row 5 and 6 I simplified the SQL
  • In the loop that starts on line 12, "contract" is a feature/row and to access the attribute you have to use the name of the field (edit that on line 14)
  • I have places the modification of the update array inside a validation of the pipe count 
  • When accessing a field by its name that contains underscores in the name, it might be better to use "$feature["Field_Name"] than $feature.Field_Name. This might not be an issue anymore, but is was some time ago.

var updates = [];
var counter = 0;

var contract_fc = FeatureSetByName($datastore,"SUDOECMS.DBO.doe_EAP_pipelineabandon_contracts", ["contract"], false);
var rowid = $feature.uniquerowid;
var sql = "parentrowid = @rowid";
var contracts = Filter(contract_fc, sql);
var cnt = count(contracts);
//var array = ["AM-094", "AM-095"]

if (cnt > 0) {
    for(var contract in contracts) {
        var abandonedpipes = FeatureSetByName($datastore,"SUDOECMS.DBO.doe_EAP_pipelineabandon", ["*"], false);
        var invoice_id = contract["NameOfFieldWithInvoiceID"]; // edit this!
        var sql2 = "invoice = @invoice_id";          
        var pipes = Filter(abandonedpipes, sql2);
        if (Count(pipes)>0) {
            var pipe = first(pipes); // why only the first???
            updates[counter] = {'globalID': pipe.GlobalID,
                                'attributes': {
                                   'q_1': $feature.status,
                                   'q_1comments': $feature["q_xcomments"],
                                   'q_1rank': $feature["q_xrank"]}
                         }
            counter++;
        }
    }
    return {'result': $feature["q_x"],
            'edit': [{'className': 'SUDOECMS.DBO.doe_EAP_pipelineabandon',
                      'updates': updates}]};
} else {
    return $feature["q_x"];
}

View solution in original post

6 Replies
XanderBakker
Esri Esteemed Contributor

Hi T L ,

When you use a "return" inside a loop, you exit the expression the first time it hits the return.  

To update multiple features you need to return a list with all the updates. Have a look at the variable "AddList" in the example "Edit another feature class with a calculation rule" at this page: Attribute rule script expression examples—ArcGIS Pro | Documentation .

TL2
by
Occasional Contributor III

Got it, thanks!  You the man!

TL2
by
Occasional Contributor III

I did get that to work, but I had hard coded in my array.  Now I am trying to create my array on insert.  Lines 8 - 11 grab the related records and put them in an array.  

This breaks on line 17 when I comment out the hard coded array (line 12, but works when using var array.  It would appear as though my array is not getting created.  Any Ideas?

var pipe = "";
var invoice = "";
var i = "";
var c = "";
var u = [];
var counter = 0;

var contract_fc = FeatureSetByName($datastore,"SUDOECMS.DBO.doe_EAP_pipelineabandon_contracts", ["contract"], false);
var sql = ("parentrowid = '" + $feature.uniquerowid + "'")
var array = filter(contract_fc, sql)
var cnt = count(array)
//var array = ["AM-094", "AM-095"]
if (cnt > 0) {
for(var c in array) 
{

    var pipe = FeatureSetByName($datastore,"SUDOECMS.DBO.doe_EAP_pipelineabandon", ["*"], false);
    var invoice = filter(pipe, "invoice = '" + array[c] + "'");
    var i = first(invoice);
        u[counter] = {'globalID': i.GlobalID,
                       'attributes': {
                           'q_1': $feature.status,
                           'q_1comments' :  $feature.q_xcomments,
                           'q_1rank' :  $feature.q_xrank
                                          }
                      }
                       counter++
    }
          return   {
               "result": $feature.q_x,
                   'edit': [{
                       'className': 'SUDOECMS.DBO.doe_EAP_pipelineabandon',
                   'updates': u
                            }]
                       }
                   }
else {
return $feature.q_x
           }‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
XanderBakker
Esri Esteemed Contributor

Hi TLongSUGF ,

I think it will be very difficult to provide working code without access to the data, but have a look at the  code below. I changed some variable name to make it a bit more understandable for me. Some observations:

  • I removed some redundant declarations from the start of the expression
  • On row 5 and 6 I simplified the SQL
  • In the loop that starts on line 12, "contract" is a feature/row and to access the attribute you have to use the name of the field (edit that on line 14)
  • I have places the modification of the update array inside a validation of the pipe count 
  • When accessing a field by its name that contains underscores in the name, it might be better to use "$feature["Field_Name"] than $feature.Field_Name. This might not be an issue anymore, but is was some time ago.

var updates = [];
var counter = 0;

var contract_fc = FeatureSetByName($datastore,"SUDOECMS.DBO.doe_EAP_pipelineabandon_contracts", ["contract"], false);
var rowid = $feature.uniquerowid;
var sql = "parentrowid = @rowid";
var contracts = Filter(contract_fc, sql);
var cnt = count(contracts);
//var array = ["AM-094", "AM-095"]

if (cnt > 0) {
    for(var contract in contracts) {
        var abandonedpipes = FeatureSetByName($datastore,"SUDOECMS.DBO.doe_EAP_pipelineabandon", ["*"], false);
        var invoice_id = contract["NameOfFieldWithInvoiceID"]; // edit this!
        var sql2 = "invoice = @invoice_id";          
        var pipes = Filter(abandonedpipes, sql2);
        if (Count(pipes)>0) {
            var pipe = first(pipes); // why only the first???
            updates[counter] = {'globalID': pipe.GlobalID,
                                'attributes': {
                                   'q_1': $feature.status,
                                   'q_1comments': $feature["q_xcomments"],
                                   'q_1rank': $feature["q_xrank"]}
                         }
            counter++;
        }
    }
    return {'result': $feature["q_x"],
            'edit': [{'className': 'SUDOECMS.DBO.doe_EAP_pipelineabandon',
                      'updates': updates}]};
} else {
    return $feature["q_x"];
}
TL2
by
Occasional Contributor III

Speechless. I added the name of the field as mentioned above and it worked.  

I will compare yours and mine to get a better understanding.  You rock!

var pipe = first(pipes); // why only the first???

This is to make sure I only have one record. If that makes sense.

XanderBakker
Esri Esteemed Contributor

Hi T L ,

Glad to hear that it works.

My comment taking the first record is that at this moment the expression will only take the first abandoned pipe and updates it for each contract or invoice. If you need all the related pipes to be updated you shouldn't take the first and loop through the results and add all globalid of the features that need to be updated. 

Edit: one additional comment. For efficiency purposes you may want to query only the GlobalID field on line 12 and not all the fields.

0 Kudos