Using Arcade to edit an attribute in another feature

1590
7
Jump to solution
03-23-2023 08:59 AM
BrianBulla
Occasional Contributor III

Hi,

So what I am doing is trying to update the Inspection Status (INSP_STATUS) of a feature, based on an inspection records that is getting populated in a separate table....both in the same database.

So far this is what I have setup as a "Validation" rule on the table the inspections get saved in.  So if the newly created inspection meets the criteria to be marked as "Out of Service" I need to update the INSP_STATUS field of the feature to "OOS".  The inspection/feature have a common field of FACILITYID.  

When I 'verify' the code I get the green check, but when I try to save the attribute rule, I get a red mark and it tells me I need to use a GlobalID.  Is there a way to do this without using the GlobalID??

 

if (($feature.OUT_OF_SERVICE != null) && ($feature.DATEWORK == null))
{
//update INSP_STATUS in the hydrant layer to OOS
return
{
'edit': [{
'classname' : 'WAT_Hydrant',
'updates' : [{
'FACILITYID' : $feature.FACILITYID,
'attributes' : {
'INSP_STATUS' : 'OOS'
}
}]
}]
}

}

0 Kudos
1 Solution

Accepted Solutions
JohannesLindner
MVP Frequent Contributor

To post code:

JohannesLindner_0-1677736512957.pngJohannesLindner_1-1677736529803.png

 

So far this is what I have setup as a "Validation" rule on the table the inspections get saved in

It has to be a Calculation Attribute Rule.

 

Is there a way to do this without using the GlobalID??

No. Attribute Rules need GlobalIDs to work.

 

You apparently already found an example of how to update another table. But take a look at the official documentation for the return dictionary. It expects certain keys, and FACILITYID is not one of them. You have to supply the objectID or globalID of the feature you want to edit.

 

 

Something like this should work (remember to enable GlobalID):

// Calculation Attribute Rule on the inspection table
// field: leave empty
// triggers: insert
// exclude from application evaluation

if (($feature.OUT_OF_SERVICE != null) && ($feature.DATEWORK == null)) {
    // get the hydrant
    var hydrants = FeaturesetByName($datastore, 'WAT_Hydrant', ['FACILITYID', 'ObjectID'], false)
    var facility_id = $feature.FACILITYID
    var hydrant = First(Filter(hydrants, 'FACILITYID = @facility_id'))
    // abort if no hydrant was found
    if(hydrant == null) { return }
    //update INSP_STATUS in the hydrant layer to OOS
    return {
        'edit': [{
            'classname' : 'WAT_Hydrant',
            'updates' : [{
                'objectID': hydrant.ObjectID,
                'attributes' : {'INSP_STATUS' : 'OOS'}
            }]
        }]
    }
}

 


Have a great day!
Johannes

View solution in original post

7 Replies
JohannesLindner
MVP Frequent Contributor

To post code:

JohannesLindner_0-1677736512957.pngJohannesLindner_1-1677736529803.png

 

So far this is what I have setup as a "Validation" rule on the table the inspections get saved in

It has to be a Calculation Attribute Rule.

 

Is there a way to do this without using the GlobalID??

No. Attribute Rules need GlobalIDs to work.

 

You apparently already found an example of how to update another table. But take a look at the official documentation for the return dictionary. It expects certain keys, and FACILITYID is not one of them. You have to supply the objectID or globalID of the feature you want to edit.

 

 

Something like this should work (remember to enable GlobalID):

// Calculation Attribute Rule on the inspection table
// field: leave empty
// triggers: insert
// exclude from application evaluation

if (($feature.OUT_OF_SERVICE != null) && ($feature.DATEWORK == null)) {
    // get the hydrant
    var hydrants = FeaturesetByName($datastore, 'WAT_Hydrant', ['FACILITYID', 'ObjectID'], false)
    var facility_id = $feature.FACILITYID
    var hydrant = First(Filter(hydrants, 'FACILITYID = @facility_id'))
    // abort if no hydrant was found
    if(hydrant == null) { return }
    //update INSP_STATUS in the hydrant layer to OOS
    return {
        'edit': [{
            'classname' : 'WAT_Hydrant',
            'updates' : [{
                'objectID': hydrant.ObjectID,
                'attributes' : {'INSP_STATUS' : 'OOS'}
            }]
        }]
    }
}

 


Have a great day!
Johannes
BrianBulla
Occasional Contributor III

Hi Jonannes.

Ok, so that error message I was getting was becuase I didn't have a GlobalID on my inspection table, so I added that, updated the code as per your sample above, and it kind of sort of works.  I don't get any errors, but I also don't get INSP_STATUS to update.

I've insert a console statement to try and do some debugging, but where to the console statements come out?  I can't seem to find a console window or anything in Pro.

0 Kudos
JohannesLindner
MVP Frequent Contributor

The console messages are visible after you verified your expression. There should be green text like "Show Messages" or something.


Have a great day!
Johannes
0 Kudos
BrianBulla
Occasional Contributor III

Hi @JohannesLindner .  Yes, I have seen that before, but in this case when I run the "Verify" it is not coming up.  Here is my code where I inserted the console message, so it should come up everytime.

But what is happening when I hit this verify?  What is this running against?  There are records in my table this rule is getting set on, but how does it (or I) know what record is being used when I hit the verify button?

 

 

 

if (($feature.OUT_OF_SERVICE != null) && ($feature.DATEWORK == null)) {
    // get the hydrant
    var hydrants = FeaturesetByName($datastore, 'WAT_Hydrant', ['FACILITYID', 'ObjectID'], false)
    var facility_id = $feature.FACILITYID
    var hydrant = First(Filter(hydrants, 'FACILITYID = @facility_id'))
    
    console(hydrant.ObjectID)

    // abort if no hydrant was found
    if(hydrant == null) { return }

    


    //update INSP_STATUS in the hydrant layer to OOS
    return {
        'edit': [{
            'classname' : 'WAT_Hydrant',
            'updates' : [{
                'objectID': hydrant.ObjectID,
                'attributes' : {'INSP_STATUS' : 'OOS'}
            }]
        }]
    }
}

 

 

 

0 Kudos
JohannesLindner
MVP Frequent Contributor

I think the verification is run on a default  object (new object with all default values). Don't quote me on this...

Your default value for OUT_OF_SERVICE is probably null, so the rule doesn't enter the if block in line 1.

 

This might also be why you're no getting the updates you expect. In its current state, the rule will only update the parent feature if

  • OUT_OF_SERVICE is not empty (it accepts any value) and
  • DATEWORK is empty

If OUT_OF_SERVICE is empty or DATEWORK is not empty, the rule will not update the parent feature. Is that the expected behavior?


Have a great day!
Johannes
BrianBulla
Occasional Contributor III

Hi @JohannesLindner 

OK, so an update here...

I made some code changes and it appears that when you run the "Verify" it is using the first record in the table, not the last.  So that definitely helps to know when troubleshooting.

So if I edit that first record, I seem to get the results I am expecting in 'verify' mode, but when adding a new record, I do not see any change to the hydrant INSP_STATUS.  Any ideas what might be going on??

 

// Calculation Attribute Rule on the inspection table
// field: leave empty
// triggers: insert
// exclude from application evaluation

console("TEST")

// get the hydrant feature
var hydrants = FeaturesetByName($datastore, 'WAT_Hydrant', ['FACILITYID', 'ObjectID'], false);
var facility_id = $feature.FACILITYID;
var hydrant = First(Filter(hydrants, 'FACILITYID = @facility_id'));

//Check for an Out of Service (OOS) inspection first
if (($feature.OUT_OF_SERVICE != null) && ($feature.DATEWORK == null)) 
{
    console("OOS")

    // abort if no hydrant was found
    if(hydrant == null) { return };

    //update INSP_STATUS in the hydrant layer to OOS
    return {
        'edit': [{
            'classname' : 'WAT_Hydrant',
            'updates' : [{
                'objectID': hydrant.ObjectID,
                'attributes' : {'INSP_STATUS' : 'OOS'}
                        }]
                }]
           };
}

 
//Next, check to see if it's a Work Required (WR) inspection
if ((($feature.HYDRANT_OPERATION != null) || ($feature.OPERATING_NUT != null) || ($feature.NOZZLE_CAPS != null) || ($feature.FLANGES != null) || ($feature.SECONDARY_VALVE != null) || ($feature.WATER_IN_BARREL != null)) && ($feature.DATEWORK == null)) 
{
    console("WR")
    // abort if no hydrant was found
    if(hydrant == null) { return };

    //update INSP_STATUS in the hydrant layer to OOS
    return {
        'edit': [{
            'classname' : 'WAT_Hydrant',
            'updates' : [{
                'objectID': hydrant.ObjectID,
                'attributes' : {'INSP_STATUS' : 'WR'}
                        }]
                }]
           };
}

//If it gets this far, then it's just a normal inspection, so set it to Inspected (YES)
console("YES")
console(hydrant.FacilityID)
if(hydrant == null) { return };
return {
    'edit': [{
        'classname' : 'WAT_Hydrant',
        'updates' : [{
            'objectID': hydrant.ObjectID,
            'attributes' : {'INSP_STATUS' : 'YES'}
                    }]
            }]
       };

 

0 Kudos
BrianBulla
Occasional Contributor III

Sorry @JohannesLindner .  I actually think it is working.  After trying again it's working now.

Thanks for your help!!  I was actually talking about this with the Field Maps team while at the Dev Summit a couple weeks ago.  It was their idea to try Attribute Rules to automate some logic we are currently using in ArcPad applications in our transition to Field Maps.  It looks like this will work.

Thanks again!

0 Kudos