Update multiple fields using key field

781
5
Jump to solution
08-22-2023 08:33 PM
Aнастасия88
Occasional Contributor

Hello, I am just stack with preparing Arcade expression for immediate calculation. By the immediate calculation, I would like to update three fields based on a table's attributes via a key field when new creation or update of a existing feature.

I have prepared a code as per below but I will get an error as per below when I create a new feature. If anyone know a solution for this, match appreciated.

// Rule for asset_july_2023
// triggers: insert, update
// field: no select

// value of shared field
var key = $feature["Asset_NAME"]

// search for related features in tbl_asset_info feature class
var assInfFS = FeatureSetByName($datastore, "tbl_asset_info", ["*"], false)
var assInfFilter = Filter(assInfFS, "Asset_NAME = @Key")

var assTabList = []
var counter = 0
var numAsset = Count(assInfFilter)
if (numAsset > 0) {
    for (var asst in assInfFilter) {
        assTabList[counter] = {
            'attributes': {          
                'ASSET_ID': asst.ASSET_ID,                
                'TYPE': asst.TYPE,
                'VALUE': asst.VALUE
            }
        }
        counter++
    }
    return {
        'edit': [{
            'className': 'asset_july_2023',
            'adds':assTabList,
            'updates': assTabList
        }]
    }
} else {
    return 'No common asset in the asset info table.'
}

A88_0-1692761166630.png

 

Tags (2)
0 Kudos
1 Solution

Accepted Solutions
JohannesLindner
MVP Frequent Contributor

I would like to extract attribute from a table to update attributes of a point feature class 

Ah. Well, that is not what your original attribute rule does (and so it's also not what my rule does). These rules will do it the other way around: They will update/add a row in the table when you update/add a point in the feature class.

No worries, what you want is actually easier:

// Calculation Attribute Rule on asset_july_2023
// trigers: Insert, Update
// field: empty

// get the first related row from tbl_asset_info
var key = $feature.Asset_NAME
var asset_infos = FeatureSetByName($datastore, "tbl_asset_info", ["*"], false)
var asset_info = First(Filter(asset_infos, "Asset_NAME = @Key"))

// abort if no related row was found
if(asset_info == null) { return }

// return the related row's attributes
return {
    result: {
        attributes: {
            ASSET_ID: asset_info.ASSET_ID,
            TYPE: asset_info.TYPE,
            VALUE: asset_info.VALUE,
            }
        }
    }

 

The null check in line 11 will solve your error message.


Have a great day!
Johannes

View solution in original post

5 Replies
JohannesLindner
MVP Frequent Contributor

The Attribute Rule needs to know which features it has to update. That is why you have to supply the GlobalID or OBJECTID of the features in the update array. Take a look at the documentation of the return dictionary.

Some other problems:

  • You're using an outdated method of appending elements to an array (counter++). If you're using ArcGIS Pro 2.7+ / Enterprise 10.9+, you can use Push().
  • When you don't find related features, you return a string, but the rule has no assigned field. I don't actually know if that will give an error, but it's useless at least, nobody will see that message.
  • Instead of using Count() (slower) and the error message, just do the for loop and return the result. If the update array is empty, nothing will happen.
  • You're using the values that are already in the asset info table, so nothing will change. You have to use the attributes of $feature
  • You're using assTabList for updates and adds. This will update the features in tbl_asset_info and add new ones, giving you duplicates. What you want to do is this:
    • If you're inserting a new features, use adds
    • If you're updating a feature, use updates
// Rule for asset_july_2023
// triggers: insert, update
// field: no select

// arrays that store adds and updates to the asset info table
var assAdds= []
var assUpdates = []

// attributes of the $feature
var featureAttributes = {          
  'ASSET_ID': $feature.ASSET_ID,                
  'TYPE': $feature.TYPE,
  'VALUE': $feature.VALUE
  }

// if this is an insert, add a new asset info feature
if($editcontext.editType == "INSERT") {
  var newAss = {
    'attributes': featureAttributes
    }
   Push(assAdds, newAss)
}

// if this is an update, edit all related asset info features
if($editcontext.editType == "INSERT") {
  // value of shared field
  var key = $feature["Asset_NAME"]
  // search for related features in tbl_asset_info feature class
  var assInfFS = FeatureSetByName($datastore, "tbl_asset_info", ["*"], false)
  var assInfFilter = Filter(assInfFS, "Asset_NAME = @Key")
  for(var asst in assInFilter) {
    var update = {
      "globalID": asst.GlobalID,
      'attributes': featureAttributes
      }
    Push(assUpdates, update)
  }
}

return {
  'edit': [{
    'className': 'asset_july_2023',
    'adds': assAdds,
    'updates': assUpdates
    }]
  }

 


Have a great day!
Johannes
Aнастасия88
Occasional Contributor

Hi Johannes,

What I would like to do actually is extracting attributes from a table to update attributes of a point feature class (asset_july_2023). So I have modified the given code as per below screenshot but still not work. Error says Unexpected null for the line 19.

// Rule for asset_july_2023 (poihnt)
// triggers: insert, update
// field: no select

// arrays that store adds and updates to the asset info table
var assAdds= []
var assUpdates = []

  // value of shared field
  var key = $feature["Asset_NAME"]
  // search for related features in tbl_asset_info feature class
  var assInfFS = FeatureSetByName($datastore, "tbl_asset_info", ["*"], false)
  var assInfFilter = First(Filter(assInfFS, "Asset_NAME = @Key"))

// if this is an insert, add a new asset_july_2023 point feature
if($editcontext.editType == "INSERT") {
  var newAss = {
    'attributes': {          
        'ASSET_ID': assInfFilter.ASSET_ID,                
        'TYPE': assInfFilter.TYPE,
        'VALUE': assInfFilter.VALUE
        }
    }
   Push(assAdds, newAss)
}

// if this is an update, edit all related asset_july_2023 point feature
if($editcontext.editType == "UPDATE") {
    var update = {
        "globalID": assInfFilter.GlobalID,
        'attributes': {          
            'ASSET_ID': assInfFilter.ASSET_ID,                
            'TYPE': assInfFilter.TYPE,
            'VALUE': assInfFilter.VALUE
            }
        }
    Push(assUpdates, update)
}

return {
  'edit': [{
    'className': 'asset_july_2023',
    'adds': assAdds,
    'updates': assUpdates
    }]
  }

 

 

 

 

 

 

0 Kudos
JohannesLindner
MVP Frequent Contributor

I would like to extract attribute from a table to update attributes of a point feature class 

Ah. Well, that is not what your original attribute rule does (and so it's also not what my rule does). These rules will do it the other way around: They will update/add a row in the table when you update/add a point in the feature class.

No worries, what you want is actually easier:

// Calculation Attribute Rule on asset_july_2023
// trigers: Insert, Update
// field: empty

// get the first related row from tbl_asset_info
var key = $feature.Asset_NAME
var asset_infos = FeatureSetByName($datastore, "tbl_asset_info", ["*"], false)
var asset_info = First(Filter(asset_infos, "Asset_NAME = @Key"))

// abort if no related row was found
if(asset_info == null) { return }

// return the related row's attributes
return {
    result: {
        attributes: {
            ASSET_ID: asset_info.ASSET_ID,
            TYPE: asset_info.TYPE,
            VALUE: asset_info.VALUE,
            }
        }
    }

 

The null check in line 11 will solve your error message.


Have a great day!
Johannes
Aнастасия88
Occasional Contributor

Thank you Johannes,

It works fine. Also, thanks for the other option that works the other way around. I am going to adjust some parameters to agree with the rules and play around that as well. 

 

0 Kudos
ChristopherBowering
Occasional Contributor II

Hi @Aнастасия88 ,

I am trying to do something similar to what both you and Johannes have laid out.  However, I am using a GlobalID (parent feature class) to GUID (table) relationship.  I am struggling with how to incorporate that into your examples since I don't have a common 'key' field that is shared between the feature class and table.  Would you be able to advise how to do this?  Thanks!

PREVIEW
 
 
 
0 Kudos