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, you can sign up for an ArcGIS free trial.

  2. Open the preexisting web map Global Power Generation and Consumption 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 lesson, you can use the resulting map from that lesson instead.

  3. On the Contents 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 map.

    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 lessons on Arcade, see this Arcade learning path.

  5. On the Contents (dark) toolbar, click Layers.

    Layers button

    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 Configure 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 Riyadh Ref power plant in Saudi Arabia. It already contains some meaningful information about this specific power plant. The Arcade expression you'll create in this lesson 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 lesson.

    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 Globals, Functions, and Constants tabs are where you find the elements you'll use in the expression.
    • The Globals 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 lesson.
    • The Functions tab lists all the Arcade functions and their integrated help on parameters, syntax, and usage.
    • The Constants tab provides a set of values and expression building blocks that are constant and do not change.

    Arcade expression editor overview

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

  11. Click Test.

    Test button

    The Results and Messages tabs appear.

    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 Globals 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. Click the Existing tab. Next to Estimated Annual Generation in Lightbulbs, click the information button.

    Click the information button.

    The Estimated Annual Generation in Lightbulbs expression appears in a preview pane.

  7. 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.

  8. 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.

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

    Add the line return countryName.

    In the Results 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.

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

    In the Results 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.

  11. In the Expression window, edit the line again to read return annualGenerationGwh and click Test.

    In the Results window, no value is listed and the Type 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.

  12. Click the Globals tab. If necessary, expand the $feature item by clicking the arrow to see the list of attributes.
  13. For $feature["estimated_generation_gwh"], click the edit button.

    Click the edit button.

  14. In the text field, type 10.

    Type the value 10.

  15. Click the Test button again.

    This time, the test value 10 (gigawatt-hours or gWh) is returned. You'll use this test value for the upcoming sections of the lesson.

    Results window showing the value 10.

    Note:

    Modifying a test value as you just did has no effect on the source data.

    The custom test value you just entered is temporary. If you close the expression editor and return to work on your expression later, you'll need to set this test value again.

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

    Remove the return statement.

    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.

  17. At the top of the editor window, next to the title, click Edit.

    Click the Edit button for the title.

    The title can now be edited.

  18. Name the expression Number of Citizens the Power Plant can Supply Annually. Click Save.

    New title for the expression

  19. At the bottom of the editor window, click OK to close the expression editor.
  20. 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 Globals tab. Expand the $map item by clicking the arrow.

    Expand $map.

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

  4. Under the World Countries Electricity Consumption layer, click FeatureSetByName(…).

    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 lesson, 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 lesson, 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).

  5. For the FeatureSetByName() line, after "World Countries Electricity Consumption", 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.

  6. In the Expression window, on the next empty line, type return countriesGenFset. Click Test.

    Type return countriesGenFset.

    In the Results 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.

  7. In the Expression window, above the return FeatureSet statement, press Enter to add a new line and type var filteredCountryFSet =.
  8. Click the Functions tab, and type Filter in the search box. In the search results, click Filter to add it to your statement.

    Filter function

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

    Note:

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

    Information button

  9. 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.

  10. Modify the return statement to read return filteredCountryFSet and click Test.

    Form the statement return filteredCountryFSet.

    In the Results window, the table 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.

    An example that uses Intersects() is provided in the finished map for this lesson. You can find it in the list of pop-up expressions of the Global Power Plants layer, under the name Intersect: Find Number of Citizens that Power Plant can Supply. The lesson Build an app to expand food access also 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.

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

    Type var filteredCountry =.

  12. On the Functions tab, search for the First function, and click it to insert it in your statement.

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

  13. Replace the argument placeholder to read as follows:

    var filteredCountry = First(filteredCountryFset)

  14. Modify the return statement to read return filteredCountry and click Test.

    Form the statement return filteredCountry.

    In the Results 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 Globals tab. If necessary, click the Back button. Expand the $map item by clicking the arrow.
  2. Expand the Layer: World Countries Electricity Consumption item by clicking the arrow.

    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 line, and type the following:

    var electricityConsumption = filteredCountry.Annual_Electricity_Consumption_

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

    Form the statement return electricityConsumption.

    In the Results 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.

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

    Form the statement return population.

    In the Results 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.

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

    var consumptionPerCapita = electricityConsumption / population

  8. Modify the return statement to read return consumptionPerCapita and click Test.

    Form the statement return consumptionPerCapita.

    In the Results 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.

  9. In the Expression window, add a new line above the return statement, and type var numCitizensAnnually =.
  10. 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(fieldOrValue, numPlaces). In place of fieldOrValue, you'll insert the formula delineated above.

  11. Replace fieldOrValue with (annualGenerationGwh * 1000000) / consumptionPerCapita .

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

  12. Replace numPlaces with 0 to obtain an integer.
  13. Modify the return statement to read return numCitizensAnnually and click Test.

    Form the statement return numCitizensAnnually.

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

    Results window showing the value 67800

    Note:

    If the result is empty for you, you may need to reenter a test value of 10 for the default power plant. To do this, go to the Globals tab, expand the $feature item by clicking the arrow, click the $feature["estimated_generation_gwh"] edit button, and type 10.

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

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

    The function is added with argument placeholders: fieldOrValue and '#,###'. The '#,###' argument specifies the text formatting for the number. The pound signs (#) are placeholders to indicate where each digit of the number will go. For example, '#,###' applied to 5783 will yield 5,783.

  16. Replace fieldOrValue with numCitizensAnnually and '#,###' with '###,###,###' to accommodate greater values.
  17. Modify the return statement to read return displayNumCitizensAnnually and click Test.

    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.

  18. In the Expression window, add a new line above the return statement, and type 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 to a template literal, because they will be displayed in the output.

  19. Modify the return statement to read return dataTL and click Test.

    Form the statement return dataTL.

    In the Results 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 lesson 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 Existing tab. If Estimated Annual Generation in Lightbulbs isn't open, click the Information button to open it in the preview pane.
  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 lesson.

    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. Click the Globals tab, expand the $feature item by clicking the arrow, click the $feature["estimated_generation_gwh"] edit button, and delete the 10 value.
  6. Click Test.

    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. On the Globals tab, for $feature["estimated_generation_gwh"], add the 10 test value again.

    You'll now address the second case of missing values: when the country name does not exist in the World Countries Electricity Consumption layer. You'll again use the IsEmpty() function to check whether filtering the FeatureSet by the country name turned up any results.

  8. In the Expression window, after the line declaring the filteredCountry variable, add a new line and type var countryCheck =. On the Functions tab, search for and click IsEmpty to add it to your statement.

    The IsEmpty() function is added with the placeholder argument, fieldOrValue.

  9. Replace fieldOrValue with filteredCountry.
  10. Add a line after the var countryCheck statement, type return countryCheck, and click Test.

    Add return countryCheck.

    Note:

    Currently, you have two return statements in your expression. Arcade always stops at the first return statement it encounters and outputs that value. In that case, the rest of the expression is not executed.

    In the Results window, the value false appears.

    Results window showing the false value

    This false result makes sense because you know Afghanistan exists in the World Countries Electricity Consumption dataset, so the FeatureSet filtered by country is not empty. For the cases in which the country is empty, you'll create a message to be returned to the pop-up. You'll use a conditional if expression and template literal to accomplish this.

  11. In the Expression window, remove the return countryCheck statement.
  12. In the same location, add a new line and type:

    if (countryCheck) {

    var noDataTL = `${ countryName } was not found in the World Countries: Population and Annual Electricity Consumption dataset.`

    return noDataTL

    }

    Add countryCheck test.

    Note:

    If(countryCheck) is a conditional statement that enables you to evaluate if countryCheck is true or false. Besides the if/else syntax, you can also use the built-in functions iif() or when() to create conditional statements. For more details, see How do I write if/else logic.

    To confirm that this is working well, you'll change the Global Power Plants country test value to a string that is not a country name.

  13. If necessary, click the Globals tab and click Back to return to the list of attributes. Click the $feature["country_long"] edit button, delete Afghanistan, and type Tatooine Instead.

    Type Tatooine.

  14. Click Test.

    In the Results window, a message displays saying that Tatooine was not found in the World Countries dataset.

    Results window showing the error message about Tatooine.

    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.

  15. 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 San Marino, which is a country in the World Countries Electricity Consumption layer that does not have annual power consumption data.

  16. On the Globals tab, for feature["country_long"], replace Tatooine with San Marino.
  17. Click Test.

    In the Results 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.

  18. Click OK to close the expression editor.
    Note:

    As you close the expression editor, test values such as San Marino will be removed and the original layer data will remain unaffected.

  19. 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 lesson 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)

// Check if the country listed in the powerplants layer exists in
// the World Countries Electricity Consumption layer. This will handle missing or different
// data in the World Countries Electricity Consumption layer. Returns true if empty.
var countryCheck = isEmpty(filteredCountry)

// Return a sentence if the country is absent from/different in
// world countries layer. If the country is absent from the world
// countries layer, this statement will execute and we'll exit the script
if (countryCheck) {
  var noDataTL = `${ countryName } was not found in the World Countries: Population and Annual Electricity Consumption dataset. Unable to calculate the number of citizens the power plant can supply electricity for annually.`
  return noDataTL
}
// 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 click the text that appears below.

    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. On the Contents toolbar, click Save and open, and choose Save to 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 lesson, 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 lesson 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.