Access attributes from another layer with ArcGIS Arcade

Get set up

First, you'll set up a web map in Map Viewer and add a new Arcade expression. You'll start with a preexisting web map, which already contains some data layers and Arcade expressions. You'll copy that map to your ArcGIS Online account so that you can start editing it and add new elements to it.

  1. Sign in to your ArcGIS organizational account.
    Note:

    If you don't have an organizational account, see options for software access.

  2. Open the Global Power Generation and Consumption web map in your web browser.

    The map appears in Map Viewer with the Legend pane open.

    Initial view

    Note:

    ArcGIS Online offers two map viewers for viewing, using, and creating maps. Map Viewer is the next-generation map making tool for ArcGIS Online. It aims to inspire experimentation and creativity while providing an enhanced experience for key map authoring workflows. For more information on the map viewers available and which to use, see this FAQ.

    The Legend pane lists two layers:

    • Global Power Plants contains a comprehensive inventory of power plants around the world.
    • World Countries Electricity Consumption contains population and electricity consumption information about every world country.
    Note:

    If you previously completed the Get started with ArcGIS Arcade tutorial, you can use the resulting map from that tutorial instead.

  3. On the Contents (dark) toolbar, click Save and open and choose Save as.

    Save button

  4. In the Save map window, for Title, add your initials at the end of the title to ensure it is unique in your organization and click Save.

    Save map window

    The map copy appears and is now ready for you to edit. Next, you'll add a new Arcade expression to the map, for use in the Global Power Plants layer pop-ups.

    Note:

    ArcGIS Arcade is a portable, lightweight, and secure expression language written to dynamically work with your data in ArcGIS. Like other programming languages, it can perform mathematical operations, manipulate text, and evaluate logical statements. It allows users to manipulate existing data and derive new insights through authoring, sharing, and executing custom expressions in ArcGIS Pro, ArcGIS Runtime, ArcGIS Online, ArcGIS Enterprise, and the ArcGIS API for JavaScript. In Map Viewer, Arcade is useful when working with data in pop-ups and labels, and when styling a layer. For more tutorials on Arcade, see this Arcade learning path.

  5. On the Contents toolbar, click Layers.

    Layers button

    Note:

    By default the side toolbars may only show the tool icon rathe than its name. You can click the expand button at the bottom of each toolbar to see the names. The images in the tutorial are of the toolbars expanded.

    The Layers pane appears.

  6. In the Layers pane, click the Global Power Plants layer to select it.

    Global Power Plants layer

  7. On the Settings (light) toolbar, click Pop-ups.

    Configure pop-ups button

    The Pop-up pane and a preview of a pop-up appear.

    Pop-up example

    It is the pop-up for the SMN Barka power plant in Saudi Arabia. It already contains some meaningful information about this specific power plant. The Arcade expression you'll create in this tutorial will add one more paragraph of text in the pop-up.

  8. Close the pop-up.
    Note:

    Alternatively, you can open the pop-up for any power plant on the map. On the map, use the mouse's wheel button to zoom in on an area of interest, for instance, Sevilla, Spain. Then, click one of the power plant points.

  9. In the Pop-ups pane, click Attribute expressions.

    Click Attribute expressions.

    Note:

    There are already two existing expressions for the pop-up in the Global Power Plants layer. These expressions are used to determine the text color for the energy type and to calculate the number of 60-watt lightbulbs that the power plant can power, both currently displayed in the power plants pop-up. Arcade enables you to reuse all or parts of these existing expressions in your new expressions. This is one of the things you'll learn in this tutorial.

    The Attribute expressions pane appears.

  10. In the Attribute expressions pane, click Add expression to open the Arcade expression editor.

    Add expression button

    The Arcade expression editor appears. This is where you'll create and edit Arcade expressions. You'll first review its components.

    • The Expression window is where you write the code.
    • The Profile variables tab offers a list of predefined variables, including attribute fields and geometry for the layer features.
    • The Functions tabs lists all the Arcade functions. You can click the information button to the right of each function to access the function's integrated help on parameters, syntax, and usage..
    • The Suggestions tab gives you access to the attributes and geometry of the layer's features through a list of predefined variables. It also enables accessing features from other layers in the web map, which you will do later in this tutorial.
    • The Help tab opens the Arcade help webpage

    Arcade expression editor overview

    The Arcade expression editor also enables you to test your expression as you are developing it, using the Run button.

  11. Click Run.

    Test button

    The Output, Console and Log tabs appear. Once you've created your expression, you can use the Run button to test the output of your expression. For now, you have not written any Arcade code, so these tabs do not contain much.

    Results and Messages tabs

    • The Results tab will display the output of the expression.
    • You can also add Console() functions to your code and see their value in the Messages tab.

    For now, you have not written any Arcade code, so the Results and Messages tabs do not contain much.

Initialize variables

Next, you'll start writing the code for your Arcade expression. It will be organized three parts:

  • First, you'll initialize (create) several variables to hold values that you'll need later in the Arcade expression.
  • Next, you'll create a FeatureSet from the World Countries Electricity Consumption layer to be able to use attributes from that layer in your expression.
  • Finally, you'll use all that data to derive new information, computing for how many citizens each power plant can provide electricity.

In this section, you'll focus on initializing and testing the variables.

  1. In the Expression window, delete the first three lines, which are not needed.

    Delete the first three lines.

    You'll create a first variable, countryName, to contain the name of the country where the power plant is located. In Arcade, you use the syntax Var <variableName> = <someValue> to set variables for later use in the expression.

  2. In the Expression window, type (or copy and paste) var countryName = .

    Create countryName variable.

    You'll specify the variable's value by fetching the corresponding attribute in the Global Power Plants layer.

  3. If necessary, click the Profile variables tab. Expand the $feature item by clicking the arrow.

    Expand the $feature item.

    The list of attributes for the Global Power Plants layer appears.

    Note:

    As mentioned, this Arcade expression will run when the user clicks a specific power plant on the map and the informational pop-up for that feature is displayed. The $feature item gives you access to the data for that specific power plant feature in the Global Power Plants layer. This includes all its attributes and its geometry.

    This differs from $layer, which accesses all the features in the layer instead of a single feature. For example, you can use $layer to get the average of an attribute value across all the features in a feature layer.

  4. In the attribute list, scroll down and click $feature.country_long.

    Click $feature["country_long"].

    Your first line of code is complete.

    First line of code

    The expression will also need variables holding the power plant's name and its estimated annual power generation. Instead of creating these two variables from scratch, you'll copy existing code from one of the preexisting Arcade expressions.

  5. Press Enter to start the next line of the expression.

    Add a line return.

  6. In the preview pane, highlight the following two lines of code and press Ctrl+C to copy them.

    var plantName = $feature.name

    var annualGenerationGwh = $feature["estimated_generation_gwh"]

    Copy variable definitions.

    Note:

    You can also copy the lines by right-clicking the highlighted text and choosing Copy.

  7. In the Expression window, press Ctrl+V to paste the code.

    Paste variable definitions.

    Note:

    You can also paste the lines by right-clicking the insertion point and choosing Paste.

    You'll now test these variable statements to ensure they work as they should. You'll do this by adding a return statement at the end of your code, starting with the first variable.

  8. In the Expression window, press Enter to start the next line of code and type return countryName. Click Run.

    Add the line return countryName.

    In the Output window, the final output of the script appears. It is the value of the return statement and shows Afghanistan.

    Results window showing Afghanistan

    This is because, for testing purposes, the expression editor uses the first feature in the attribute table. In this case, the first feature is a power plant in Afghanistan. You'll now test the value of the second variable.

  9. In the Expression window, edit the last line of your script to read return plantName. Click Run.

    In the Output window, the value Kajaki Hydroelectric Power Plant Afghanistan appears, which is the name of that same default Afghani power plant.

    The Results window showing Kajaki Hydroelectric Power Plant Afghanistan

    You'll now test the value of the third variable.

  10. In the Expression window, edit the line again to read return annualGenerationGwh and click Run.

    In the Output window, no value is listed and the result is Null.

    Results window showing a Null result

    This is because the default power plant, Kajaki Hydroelectric Power Plant Afghanistan, has no estimated annual power generation data. In such a case, you can manually specify a different value for testing purposes.

  11. Above the line return annualGenerationGwh, add the function annualGenerationGwh = 10 and click Run.

    Add a line of code

    In the Output window, the value 10 (gigawatt-hours or gWh) is returned. You'll use this test value for the upcoming sections of the tutorial

  12. In the Expression window, delete the line return annualGenerationGwh, as you won't need it any more.

    Before developing your expression further, you'll name it and save it. It is important to give a name to any expression you create to make it easier to identify it and use it in your map.

  13. At the top of the editor window, click and highlight New expression and delete the text. Type Number of Citizens the Power Plant can Supply Annually.

    New title for the expression

  14. At the bottom of the editor window, click Done to close the expression editor.

    Attribute expressions list

    The expression appears in the Attribute expressions heading.

  15. On the Contents toolbar, click Save and open, and choose Save to save your map and the Arcade expression.

    Save button

    Note:

    It is recommended that you save the Arcade expression and the map regularly.

Obtain data from a different layer

To find the number of citizens that a power plant can supply electricity for in the Global Power Plants pop-up, you need to divide the estimated annual electricity generation from the power plant by the electricity consumption per capita in the country where the power plant is located.

You already obtained the first number in the previous section, and it is stored in the annualGenerationGwh variable. The second number can be derived from the population and total electricity consumption attributes in the World Countries Electricity Consumption layer. This means that you'll need to access the World Countries Electricity Consumption attributes in the Global Power Plants pop-up. You'll do this by creating a FeatureSet.

A FeatureSet allows you to access features from any layer within the map or from a feature service external to the map. You can then filter the features accessed based on criteria of relevance. In your case, you'll access the World Countries Electricity Consumption features (that is, the list of all the world countries with their attributes), and you'll look for the one country where the current power plant is located. For instance, for the Kajaki Hydroelectric Power Plant, you'll filter down the list to the single Afghanistan feature. This way, the Global Power Plants feature will be connected to the relevant World Countries Electricity Consumption feature, because of the matching country name attribute values. Learn more about FeatureSets in the Arcade documentation.

Note:

Due to the processing time for queries that return a lot of data, FeatureSets may not perform as well with larger datasets.

You'll now create the FeatureSet using FeatureSetByName.

Note:

FeatureSetByName is one of several options to create a FeatureSet.

  1. In the Attribute expressions pane, click Number of Citizens the Power Plant can Supply Annually to reopen the expression in the Arcade expression editor.

    Reopen the expression.

  2. In the Expression window, on the next empty line, type var countriesGenFset =.
  3. If necessary, click the Profile variables tab. Expand the $map item by clicking the arrow.

    Expand $map.

    The list of all the layers contained in the map appears.

  4. Under Layers, for World Countries Electricity Consumption, click the arrow.

    Expand the World Countries Electricity Consumption layer.

  5. Under World Countries Electricity Consumption, click FeatureSetByName($map, "World Countries Electricity Consumption").

    Click FeatureSetByName.

    The FeatureSetbyName function is added to the Expression window. In the Expression window, the statement looks like this:

    var countriesGenFset = FeatureSetByName($map, "World Countries Electricity Consumption")

    Define the countriesGenFset variable.

    FeatureSetByName() uses the $map value for its first parameter, essentially saying to look for this layer in the current map. The second parameter is the name of the layer itself. It must match the layer name in the Layers pane.

    You'll now add some optional arguments to the FeatureSetByName() function to make your FeatureSet definition more specific.

    Note:

    Some optional arguments can be added to the FeatureSetByName() function.

    You can specify which specific attributes you are interested in to avoid loading the entire attribute table. For instance, in this tutorial, you are only interested in the country's name, total annual electricity consumption, and total population. Requesting only the fields you need increases performance because less data needs to be sent.

    You can also request to include the geometry in the FeatureSet, so that you can gain access to the polygons for each country. This is done with a Boolean (a value that is either true or false). In this tutorial, you won't need the geometry, so you will set the Boolean to false. Not requesting geometry also improves performance, and as a general rule geometry should only be included when needed in the expression.

    If these parameters are left blank, all attributes and geometry are included in the FeatureSet.

    Next, you will modify the FeatureSetByName() line so the FeatureSet will only contain the three fields you need and will not contain the geometry.

    Note:

    Since the statement is long, it is recommended that you divide it into several lines to improve the legibility. You should add the line breaks between arguments (after each comma).

  6. For the FeatureSetByName() line, after "World Countries Electricity Consumption", delete the end parenthesis and type a comma. Copy and paste the following text:

    ['COUNTRY', 'Annual_Electricity_Consumption_', 'POP'], false)

    Add parameters to FeatureSetByName().

    You'll add a return statement to test and inspect the FeatureSet.

  7. In the Expression window, on the next empty line, type return countriesGenFset.

    Type return countriesGenFset.

  8. Click Run.

    In the Output window, the FeatureSet is returned. It is a set of all the features in the World Countries Electricity Consumption layer, with only the attributes that you requested.

    Results showing the FeatureSet table

    You'll now use the Filter() function to filter the FeatureSet rows, using the value stored in the countryName variable. Filter() takes two parameters: the layer or FeatureSet to be filtered, and the SQL expression that does the filtering.

  9. In the Expression window, above the return countriesGenFset statement, press Enter to add a new line and type var filteredCountryFSet =.
  10. Click the Functions tab, and in the search box, type Filter. In the search results, click Filter(features, sqlExpression) to add it to your statement.

    Filter function

    Filter() is added to the expression editor with two argument placeholders, features and sqlExpression.

    Note:

    On the Functions tab, you can obtain more information about any function by clicking the arrow button next to the function's name.

    Information button

  11. Edit the Filter() argument placeholders to form the following statement:

    var filteredCountryFSet = Filter(countriesGenFset, 'COUNTRY = @countryName')

    The @ in @countryName signifies that countryName is a variable defined earlier in the expression. This SQL expression looks through all the rows in the FeatureSet and keeps only the ones where the COUNTRY attribute has the same value as the countryName variable (for instance, Afghanistan). The variable filteredCountryFSet will only contain the FeatureSet rows that pass the test.

  12. Modify the return statement to read return filteredCountryFSet and click Run.

    Form the statement return filteredCountryFSet.

    In the Output window, the window now contains only the row for Afghanistan.

    Results window showing a single row for Afghanistan

    Note:

    There are other ways of filtering the features in a FeatureSet. If a FeatureSet includes the features' geometry, the Arcade functions Intersects() and Contains() can accomplish the same end goal of connecting features in the FeatureSet with features in the pop-up layer. This is useful for situations in which the two layers do not share a common attribute, but the layers' features intersect spatially in a meaningful way.

    The tutorial Build an app to expand food access uses the Intersects() functionality.

    Even though the variable filteredCountryFset contains only one row, it is still a FeatureSet, and the row is wrapped into a table structure. Next, you'll extract the data from the table, so that you can use it more easily. In Arcade, the function First() is commonly used in that case. It takes the first feature out of a FeatureSet and returns it.

  13. In the Expression window, add a new line above the return filteredCountryFSet statement, and type var filteredCountry =.

    Type var filteredCountry =.

  14. On the Functions tab, and in the search box, type first. Under FeatureSet functions, click First(features) -> Feature to add it to the expression.

    First(features) -> Feature function

    The function is added with an argument placeholder: First(features).

  15. Replace the argument placeholder to read as follows:

    var filteredCountry = First(filteredCountryFset)

  16. Modify the return statement to read return filteredCountry and click Run.

    Form the statement return filteredCountry.

    In the Output window, the data now appears as a single feature.

    Results window showing a single feature

    You'll use this data in the next few statements of the Arcade expression.

Calculate the electricity supply

You'll now use the information you extracted from the FeatureSet to calculate the number of citizens a power plant can supply electricity for. Then, you'll format the resulting number.

First, you'll obtain the annual electricity consumption for the power plant's country. This data is stored in the filteredCountry feature, in its Annual_Electricity_Consumption_ attribute field. To access a feature's attributes in Arcade, use the syntax feature["attribute"] or feature.attribute.

You saw in your previous test results that this attribute is called Annual_Electricity_Consumption_. However, another way to find this information is to explore the fields interactively in the Globals pane.

  1. Click the Profile variables tab. If necessary, click the Back button. Expand the $map item by clicking the arrow.
  2. Under the Layer group, click the arrow for World Countries Electricity Consumption.

    The list of attributes for the layer appears, including the Annual_Electricity_Consumption_ attribute.

    Annual_Electricity_Consumption_ attribute

    Now that you have identified with certainty the name of the attribute of interest, you'll write the statement to add it to a variable.

  3. In the Expression window, add a new line above the return filteredCountry line, and type the following:

    var electricityConsumption = filteredCountry.Annual_Electricity_Consumption_

  4. Modify the return statement to read return electricityConsumption and click Run

    Form the statement return electricityConsumption.

    In the Output window, since the test country is Afghanistan, you see Afghanistan's annual electricity consumption returned: 5526000000 (kilowatt-hours or kWh).

    Results window showing the value 5526000000

    Similarly, you'll access the population data stored in the filteredCountry feature.

    Because you have set theannualGenerationGwh = 10, the output is 0. You must delete that value from the code to run based on the given values from the attribute table.

  5. Delete the line annualGenerationGwh = 10 and click Run.
  6. In the Expression window, add a new line above the return statement, and type var population = filteredCountry.POP;.
  7. Modify the return statement to read return population and click Run.

    Form the statement return population.

    In the Output window, you can see Afghanistan's total population: 37466414.

    Results window showing the value 37466414

    Next, you'll calculate the consumption per capita, which is the estimated annual consumption divided by the population.

  8. In the Expression window, add a new line above the return statement, and type the following:

    var consumptionPerCapita = electricityConsumption / population

  9. Modify the return statement to read return consumptionPerCapita and click Run.

    Form the statement return consumptionPerCapita.

    In the Output window, you can see that the consumption per capita is 147.4920978559624 (kWh).

    Results window showing the value 147.4920978559624

    To obtain the estimated number of citizens that the power plant can provide electricity for annually, you'll divide the estimated annual electricity generation data from the power plant (converted from gWh to kWh by multiplying by 1000000) by the electricity consumption per capita for the country that you just computed (in kWh).

    The corresponding formula will be annualGenerationGwh * 1000000) / consumptionPerCapita.

    You'll then use the Round() function to return a whole number instead of a decimal, because people should be represented in whole numbers.

  10. In the Expression window, add a new line above the return statement, and type var numCitizensAnnually =.
  11. On the Functions tab, search for the Round function, and click it to insert it in your statement.

    The function is added with argument placeholders: Round(value, ). In place of value, you'll insert the formula delineated above.

  12. For the Round function, in the parentheses, replace value with consumptionPerCapita, (annualGenerationGwh * 1000000) / consumptionPerCapita .

    The second Round() argument, numPlaces, indicates the number of decimal places to round the number to.

  13. After the expression, type a comma, a space, and a 0.
  14. Modify the return statement to read return numCitizensAnnually and click Run.
    Note:

    If the result is 0 for you, add back the annualGenerationGwh = 10 above the var NumCitizensAnnually = Round line.

    Form the statement return numCitizensAnnually.

    In the Output window, you can see the result of this formula: 67800 (citizens).

    Results window showing the value 67800

    You'll now format this rounded number to add thousand separators using the Text() function.

  15. In the Expression window, add a new line above the return statement, and type var displayNumCitizensAnnually = and add a space.
  16. Click the Functions tab, search for the Text function, and click it to insert it in your statement.

    Text function

    The function is added with argument placeholders: value

  17. Replace value with numCitizensAnnually and after that, type , '###,###,###' to accommodate values up to 9 digits.
  18. Modify the return statement to read return displayNumCitizensAnnually and click Run.

    Form the statement return displayNumCitizensAnnually.

    In the Results window, 67800 becomes 67,800, which is the format you were targeting.

    Results window showing the value 67,800

    The Kajaki Hydroelectric Power Plant Afghanistan power plant can supply an estimated 67,800 citizens of Afghanistan with electricity each year.

    Now that you have computed the estimated number of citizens that the power plant can provide electricity for annually, you'll return this value in a sentence that will be displayed in the pop-up. To accomplish this, you'll use a template literal and incorporate some more text formatting. A template literal is delimited by back quotes (`) and uses the syntax ${variableName} to insert variables or expressions into a string. This means that the sentence returned will vary depending on the value of the variables for each power plant in the map.

  19. In the Expression window, add a new line above the return statement, and copy and paste the following line:

    var dataTL = `On average, a citizen in ${ countryName } consumes ${ text(round(consumptionPerCapita, 0), '###,###,###,###') } kilowatt-hours of electricity per year. ${ plantName } supplies electricity for ${ displayNumCitizensAnnually } citizens in ${ countryName } annually.`

    Note:

    You should not add line breaks, because they will be displayed in the output.

  20. Modify the return statement to read return dataTL and click Run.

    Form the statement return dataTL.

    In the Output window, you can see the output sentence, where the variables have been replaced with their evaluated values.

    Results window showing the output sentence

Manage missing values

Your Arcade expression is almost ready. However, you still need to address the unusual cases in which some of the attribute values are missing. There are three important cases:

  • A power plant feature may not have estimated annual power generation data.
  • A power plant feature in the Global Power Plants layer may mention a country that does not exist in the World Countries Electricity Consumption layer.
  • The country in the World Countries Electricity Consumption layer may not have electricity consumption data.

First, you'll address the case in which the power plant does not have estimated annual power generation data. You encountered this case earlier in the tutorial with the test power plant feature, Kajaki Hydroelectric Power Plant Afghanistan. You'll reuse the work that was done in the preexisting expression Estimated Annual Generation in Lightbulbs to address these missing values.

  1. Click the Suggestions tab. For Estimated Annual Generation in Lightbulbs isn't open, click the arrow to expand and see a preview of the code.
  2. Highlight the expression excerpt starting from var generationCheck and ending with the closing brace following return noGenerationTL. Press Ctrl+C to copy it.

    Copy the generationCheck code.

  3. In the Expression windows, locate the line declaring the annualGenerationGwh variable, add a new line, and press Ctrl+V to paste the copied text.

    Paste the generationCheck code.

    Note:

    The few lines starting with // are comments, which will not affect the behavior of the expression. Optionally, you can delete them.

    The code you inserted creates a Boolean variable (true or false) from the value of the IsEmpty() function. IsEmpty() checks whether a variable is empty or null and returns True if it is. So, you are checking if the annualGenerationGwh variable, which contains the estimated annual generation field value, is empty. If it is, the if statement returns a sentence explaining the issue. You can learn more about the code that you just reused in the Get started with ArcGIS Arcade tutorial.

    You'll modify the template literal to better reflect the specific scenario that your Arcade expression is addressing.

  4. In the text you just pasted, highlight the text after var noGenerationTL = and replace it with the following text:

    `${ plantName } does not have estimated annual generation data. Unable to calculate the number of citizens the power plant can supply electricity for annually.`

    To test this case, you'll remove the test value of 10 you had added to the $feature.estimated_annual_generation attribute.

  5. In the code, find the annualGenerationGwh = 10 line and type // in front of it to comment it out..
  6. Click Run.

    The result displays the missing data sentence, which makes sense because the test feature does not have estimated annual power generation data.

    Results window showing the missing data sentence

  7. In the code, remove the comments for the annualGenerationGwh = 10 line.

    Finally, you'll take care of the third case of missing values: when a country in the World Countries Electricity Consumption layer doesn't have electricity consumption data. You'll leverage the knowledge that if the country does not have estimated annual consumption data, the electricityConsumption variable will be null.

  8. In the Expression window, after the line declaring the electricityConsumption variable, add a new line and type the following:

    if (electricityConsumption == null) {

    var noConsumptionTL = `There is no annual electricity consumption data for ${ countryName }. Unable to calculate the number of citizens the power plant can supply electricity for annually.`

    return noConsumptionTL

    }

    Add the electricityConsumption test.

    Note:

    Using the IsEmpty() function would work too, but using == null tests specifically whether the variable is null.

    To test this case, you'll use the example of Boulaos, in Djibouti, which is a country in the World Countries Electricity Consumption layer that does not have annual power consumption data.

  9. Click Done in the Expression window.
  10. On the map click the Search button and search for Djibouti and click the symbol to open the pop-up.

    In the pop-up window, a message displays saying that there is no annual electricity consumption data for San Marino.

    Results window showing the error message for San Marino

    Now that you addressed the various cases of missing data, you can be confident that your expression will always return a meaningful message to the user. Your Arcade expression is now complete.

  11. On the Contents toolbar, click Save and open, and choose Save to save your map and the Arcade expression.

    For reference, the complete expression from the tutorial is below. Comments have been added to orient the reader to the meaning of the code.


// Save the country and power plant name to variables for later use
var countryName = $feature["country_long"]

// Save the power plant name and annual generation to a variable
// for later use
var plantName = $feature.name
var annualGenerationGwh = $feature["estimated_generation_gwh"]

// Check if there is a value in the estimated annual generation
// attribute field. isEmpty(fieldOrValue) returns true if empty
var generationCheck = isEmpty(annualGenerationGwh)

// If there is not annual generation data, return a sentence for use
// in the pop-up that informs the user about this.
// The below expression uses conditional logic and a template literal:
if (generationCheck) {
  var noGenerationTL = `${ plantName } does not have estimated annual generation data. Unable to calculate the number of citizens the power plant can supply electricity for annually.`
  return noGenerationTL
}

// If there is average annual generation data, the script continues:
// Create a FeatureSet from the World Countries Electricity Consumption layer
var countriesGenFset = FeatureSetByName($map,
"World Countries Electricity Consumption",
['COUNTRY', 'Annual_Electricity_Consumption_', 'POP'], false)

// Filter the countries feature set. COUNTRY is attribute field in World
// Countries Population and Annual Electricity Consumption
// filteredCountryFset will be a FeatureSet with only one feature,
// because the powerplant country value is only equal to one country
var filteredCountryFset = filter(countriesGenFset,
'COUNTRY = @countryName')

// Select the first country in the filtered FeatureSet
// This essentially changes the data type from FeatureSet to a feature
// because in this case, there is only one feature in each FeatureSet
var filteredCountry = first(filteredCountryFset)

}
// Access the electricity consumption value for the country
// from the countries layer
// Note: bracket [] and . notation are both accepted
var electricityConsumption = filteredCountry.Annual_Electricity_Consumption_;

// Check if there is annual electricity consumption data for the country
// Instead of using isEmpty, we will check if the value is null
// If it isn't, return a sentence indicating this and exit the script
if (electricityConsumption == null) {
  var noConsumptionTL = `There is no annual electricity consumption data for ${ countryName }. Unable to calculate the number of citizens the power plant can supply electricity for annually.`
  return noConsumptionTL
}

// Access the population value for the country from the countries layer
var population = filteredCountry.POP;
// Compute the consumption per capita for that country
var consumptionPerCapita = electricityConsumption / population

// Calculate the number of citizens the plant can supply annually
var numCitizensAnnually = round(
  (annualGenerationGwh * 1000000) /
  (consumptionPerCapita), 0)

// Change the number to text so we can add thousand separators
var displayNumCitizensAnnually = Text(numCitizensAnnually,"###,###,###");

// Use a template literal to return the string we will display
// in the pop-up
var dataTL = `On average, a citizen in ${ countryName } consumes ${ text(round(consumptionPerCapita, 0), '###,###,###,###') } kilowatt-hours of electricity per year. ${ plantName } supplies electricity for ${ displayNumCitizensAnnually } citizens in ${ countryName } annually.`
return dataTL

Display results in the pop-up

Now that your Arcade expression is complete, it is time to use it in the text of the Global Power Plants layer's pop-ups.

  1. In the Layers pane, ensure that the Global Power Plants layer is selected.
  2. In the Attribute expressions pane, click the back button.

    Back button

  3. In the Pop-ups pane, at the bottom of the pane, click Text and then click Edit text.

    Text button and text

    The pop-up text editor window appears, showing the text that currently displays in the Global Power Plants layer. You'll add the result of your Arcade expression to the existing text.

  4. In the pop-up text editor, place your cursor at the end of {expression/expr1} and press Enter.
  5. Type a series of dashes (-------------------------------) to create a divider between paragraphs. Press Enter.

    Type a series of dashes.

  6. Type a single brace: {.

    A list of available fields and Arcade expressions appears.

    Type a single brace.

  7. Scroll down the list and click the expression you just created, Number of Citizens the Power Plant can Supply Annually.

    Select the expression Number of Citizens the Power Plant can Supply Annually.

    Note:

    You can see that the Arcade expression you created is listed like any of the other attribute fields that are available. You can recognize it easily, thanks to the meaningful name you gave it earlier.

    The expression is added to the Text element with the unique identifier {expression/expr2}.

    New expression added to the Text element

    Note:

    If you have added or removed any other expressions, the unique identifier may use a different number than 2, for instance, {expression/exp3}.

  8. Click OK to close the pop-up text editor.
  9. Save the map.

    You'll now test the pop-ups.

  10. Close the Pop-ups and Layers panes to free up more space on the map.
  11. Zoom in to an area of interest, for instance, Sevilla, Spain.
  12. Click a power plant to display the pop-up.

    Final pop-up

    The pop-up now displays the new paragraph of text that your Arcade expression generates.

  13. In the pop-up, review the information about the electricity consumption per citizen and the number of citizens the power plant serves.
  14. Click other power plants to view their pop-ups.

In this tutorial, you developed an ArcGIS Arcade expression to calculate the number of citizens that a power plant can supply electricity for in a year. You learned how to access data from more than one layer using FeatureSets and the Filter() function. You then used that data in some computations, addressed several cases of missing data, and used the expression in pop-ups. The Arcade expression is executed dynamically, without any effect on the underlying data. This tutorial covered only some of what you can do with Arcade. To learn more, explore the Arcade learning path.

You can find more tutorials in the tutorial gallery.