I have created a Web Map in Enterprise 11.1 Portal. One of the layers used in the web map has a joined table for connecting Tax Parcels with Ownership and Tax information.
After doing quite a bit of research, I have determined that the only way to incorporate data from the joined table is by using an Arcade Expression.
There are several descriptive articles out there but the one that I followed to make my expression is is an ESRI Technical Support How To.
I typed it out in the Arcade Playground and it appears that a single line is causing this to fail, however, after multiple attempts I still cannot figure out how to fix it. On line 23, I get an invalid expression:
I have tried switching it out with
popupString += "Parcel ID: " + DefaultValue(f.PARCELID, 'No Info') + TextFormatting.NewLine
or
popupString += "Parcel ID: " + Text(f.PARCELID) + TextFormatting.NewLine
Nothing seems to want to let this expression work.
Is there anything that I am missing? I am not good with Arcade or debugging in general, so this might be completely off. Any help or advice would be well worthwhile for me.
Solved! Go to Solution.
Ugh, I really dislike those unknown error messages. Unfortunately Arcade is full of instances where the error message is supremely unhelpful.
Okay, so that's basically exactly how I would have written it. One thing I might have done differently would be to establish the returned variables outside of the for loop and then assign them within it, something like:
//Related features as a variable
var RelatedData = Filter(RelatedTable, FilterStatement)
var pid
var oo
var ot
var pa
var sa
//creates template literals for items in array
for (var f in RelatedData){
pid = f.PARCELID
oo = f.OWNERNME1
ot = f.OWNERNME2
pa = f.PSTLADRESS
sa = f.SITEADRESS
var popup_str = `${pid}
First Owner Name: ${DefaultValue(oo, 'No Info')}
Second Owner Name: ${DefaultValue(ot, 'N/A')}
Postal Address: ${DefaultValue(pa, 'No Info')}
Property Address: ${DefaultValue(sa, 'No Info')}`}
return popup_str;
But I don't know that it makes a ton of difference. One other thing I notice is that your return statement isn't formatted the way the arcade popup element expects. Try replacing your return statement with this:
return {
type : 'text',
text : `${popupString}`
}
Are you trying this in an Arcade expression, or are you using an Arcade popup element?
Try using the popup element if you aren't, and place the variable popupString in the return statement. I adapted your syntax for a similar setup I have, and I was able to make it work by changing out some fields:
var portal = Portal("https://gis.edenprairie.org/portal/")
var RelatedTable =
// Fetches OWNER TAX TABLE from a public portal item
FeatureSetByPortalItem(
portal,
// portal item id
"ca7d0fb003174f849cbae06bf94453c1",
1, // layer id
['Date','Notes'], // fields to include
false // include or exclude geometry
);
var CommonAttr = $feature.GlobalID
var FilterStatement = 'TreeInv_Rel = @CommonAttr'
var relatedData = Filter(RelatedTable, filterStatement)
var popupString = ''
for(var f in relatedData){
popupString += Text(f.Date) + TextFormatting.NewLine +
"First Owner Name: " + DefaultValue(f.Notes,'No Info') + TextFormatting.NewLine }
return {
type : 'text',
text : popupString
}
EDIT: also note, your variable portal is lower case in the assignment, but capitalized when you go to use it. Usually variables are case sensitive, I believe, so try making that adjustment as well.
@ZachBodenner This is what I am using for the Pop-ups Arcade Expressions
var portal = Portal("https://gcarcgis.co.grant.wi.gov/")
var RelatedTable =
// Fetches OWNER TAX TABLE from a public portal item
FeatureSetByPortalItem(
portal,
// portal item id
"d65d041ad4ed48f290a4669c4607206f",
11, // layer id
['PARCELID','OWNERNME1', 'OWNERNME2', 'PSTLADRESS', 'SITEADRESS', 'SCHOOLDIST', 'SCHOOLDISTNO', 'CNTASSDVALUE', 'LNDVALUE', 'IMPVALUE', 'ESTFMKVALUE', 'NETPRPTA', 'GRSPRPTA', 'PROPCLASS', 'AUXCLASS', 'ASSDACRES', 'DEEDACRES', 'WEBPIN' ], // fields to include
false // include or exclude geometry
);
var CommonAttr = $feature.Name
var FilterStatement = 'PARCELID = @CommonAttr'
var relatedData = Filter(RelatedTable, filterStatement)
var popupString = ''
for(var f in relatedData){
popupString += Text(f.PARCELID) + TextFormatting.NewLine +
"First Owner Name: " + DefaultValue(f.OWNERNME1,'No Info') + TextFormatting.NewLine +
"Second Owner Name: " + DefaultValue(f.OWNERNME2,'N/A') + TextFormatting.NewLine +
"Postal Address: " + DefaultValue(f.PSTLADRESS, 'No Info') + TextFormatting.NewLine +
"Property Address: " + DefaultValue(f.SITEADRESS, 'None') + TextFormatting.NewLine +
"School District and ID: " + DefaultValue(f.SCHOOLDIST, 'N/A') + ' ' + DefaultValue(f.SCHOOLDIST, 'N/A') + TextFormatting.NewLine +
TextFormatting.NewLine +
"Assessment Information " + TextFormatting.NewLine +
"Total Assessed Value: $" + DefaultValue(f.CNTASSDVALUE,'No Info') + TextFormatting.NewLine +
"Land Value: $" + DefaultValue(f.LNDVALUE,'No Info') + TextFormatting.NewLine +
"Improvement Value: $" + DefaultValue(f.IMPVALUE,'No Info') + TextFormatting.NewLine +
"Estimated Fair Market Value: $" + DefaultValue(f.ESTFMVALUE,'No Info') = TextFormatting.NewLine +
TextFormatting.NewLine +
"Tax Information" + TextFormatting.NewLine +
"Gross Property Tax: $" + DefaultValue(f.GRSPRPRTA, 'No Info') + TextFormatting.NewLine +
"Net Property Tax: $" + DefaultValue(f.NETPRPTA, 'No Info') + TextFormatting.NewLine +
TextFormatting.NewLine
"Acreage Information: " + "Assessed Acres: " + DefaultValue(f.ASSDACRES, 'No Info') + " Deeded Acres: " + DefaultValue(f.DEEDACRES, 'No Info') + TextFormatting.Newline +
TextFormatting.NewLine
}
return{
DefaultValue(popupString, 'No information at this time.')}
Line 22 seems to be my problem child.
Hm, have you tried running a test by paring down the expression to just a couple of attributes? Pulling out components is a good way to troubleshoot.
But then yeah I'd second @jcarlson and try using template literals. Place your popupString return between backticks (`) and then enclose attributes/variables in ${}
Ex: $feature.ParcelID goes to ${$feature.ParcelID}
or
var p = $feature.ParcelID goes to ${p} if enclosed in template literal backticks. Then you can just use actual carriage returns to create new lines instead of the TextFormatting.
Concatenating strings like that can get really messy and hard to follow. For one thing, try using template literals to build the string all in one go. Template literals will actually respect line breaks, letting you write the output text in a way that looks like you want the output.
Second, you can use an Array together with Concatenate to join multiple strings together with line breaks. I find it easier to follow than constantly appending to the same variable, and it also allows you to sort and filter that array if you ever needed to.
var popup_arr = []
for (var f in relatedData) {
var popup_str = `${f.ParcelID}
First Owner Name: ${DefaultValue(f.OWNERNME1,'No Info')}
Second Owner Name: ${DefaultValue(f.OWNERNME2,'N/A')}
and so on
and so on
Assessment Information
Total Assessed: $${DefaultValue(f.CNTASSDVALUE,'No Info')}
and so on`
Push(popup_arr, popup_str)
}
// return every related entry separated by a new line
return Concatenate(popup_arr, '\n')
That said, I would second @ZachBodenner 's suggestion to use an Arcade popup element. You could display these attributes as a legitimate field list that way, rather than as a big block of text, making it consistent with the way a default popup looks.
You could even have a separate popup element for every section, allowing separate headers for Assessment, Tax, etc.
@ZachBodenner @jcarlson Thank you both for your input, I am rather slow and not well versed in computer language, I am going to do some research on your recommendations (ie. Tempalte Literals, carriage, etc...) and try it out. Will follow up when complete.
If it's helpful at all, here's ESRI's documentation on template literals:
https://developers.arcgis.com/arcade/guide/template-literals/
"carriage return" is just the term for hitting the Enter key on your keyboard to move to a new line.
@ZachBodenner & @jcarlson So I think I have the template literals figured out but I am not putting it all together the right way. I have also taken your advice to narrow it town a bit and this is what I came up with:
//Access 'Owner Information' table as a FeatureSet
var RelatedTable = FeatureSetByPortalItem(
Portal('https://gcarcgis.co.grant.wi.gov/'),
'd65d041ad4ed48f290a4669c4607206f',
11,
['PARCELID', 'OWNERNME1', 'OWNERNME2', 'PSTLADRESS', 'SITEADRESS'],
false
);
//Filter related features using a common attribute
var CommonAttr = $feature.Name
var FilterStatement = 'PARCELID = @CommonAttr'
//Related features as a variable
var RelatedData = Filter(RelatedTable, FilterStatement)
//creates template literals for items in array
for (var f in RelatedData){
var pid = f.PARCELID
var oo = f.OWNERNME1
var ot = f.OWNERNME2
var pa = f.PSTLADRESS
var sa = f.SITEADRESS
var popup_str = `${pid}
First Owner Name: ${DefaultValue(oo, 'No Info')}
Second Owner Name: ${DefaultValue(ot, 'N/A')}
Postal Address: ${DefaultValue(pa, 'No Info')}
Property Address: ${DefaultValue(sa, 'No Info')}`}
return popup_str;
For whatever reason, I am still getting an Unknown Error even though nothing is flagging as incorrect:
Do you have any other suggestions?
Ugh, I really dislike those unknown error messages. Unfortunately Arcade is full of instances where the error message is supremely unhelpful.
Okay, so that's basically exactly how I would have written it. One thing I might have done differently would be to establish the returned variables outside of the for loop and then assign them within it, something like:
//Related features as a variable
var RelatedData = Filter(RelatedTable, FilterStatement)
var pid
var oo
var ot
var pa
var sa
//creates template literals for items in array
for (var f in RelatedData){
pid = f.PARCELID
oo = f.OWNERNME1
ot = f.OWNERNME2
pa = f.PSTLADRESS
sa = f.SITEADRESS
var popup_str = `${pid}
First Owner Name: ${DefaultValue(oo, 'No Info')}
Second Owner Name: ${DefaultValue(ot, 'N/A')}
Postal Address: ${DefaultValue(pa, 'No Info')}
Property Address: ${DefaultValue(sa, 'No Info')}`}
return popup_str;
But I don't know that it makes a ton of difference. One other thing I notice is that your return statement isn't formatted the way the arcade popup element expects. Try replacing your return statement with this:
return {
type : 'text',
text : `${popupString}`
}
So I was watching a video about arcade and they said you can configure pop ups in ArcGIS Pro, so I pasted the expression in Pro. I looked back and never noticed you had /portal in your URL.
Added /portal/ to my URL and it looks like it worked.
I also just came to the realization that this needed to be in Attribute Expressions. So I put it all together and this is what turned up:
The next steps are to repeat this process, however, does the "return" have to be formatted as:
This in not a suitable display format
Thank you again for all of your help thus far, I am learning a lot!