Edit

Share via


AsType and IsType functions

Function Applies to
AsType Canvas apps Cards Copilot Studio Model-driven apps Power Platform CLI Dataverse functions Power Pages
IsType Canvas apps Copilot Studio Model-driven apps Dataverse functions Power Pages

Checks if a record reference is a specific table type (IsType) and treats the reference as that type (AsType).

Note

PAC CLI pac power-fx commands don't support IsType.

Description

The AsType and IsType functions can be used to convert record references (for example polymorphic lookups in Dataverse) and dynamic values to typed values that can be used directly.

Record References

Read Understand record references and polymorphic lookups for a broader introduction and more details.

A lookup field usually refers to records in a particular table. Because the table type is well established, access the fields of the lookup using simple dot notation. For example, First( Accounts ).'Primary Contact'.'Full Name' walks from the Accounts table to the Primary Contact record in the Contacts table and extracts the Full Name field.

Microsoft Dataverse also supports polymorphic lookup fields, which can refer to records from a set of tables, as in these examples.

Lookup field Can refer to
Owner Users or Teams
Customer Accounts or Contacts
Regarding Accounts, Contacts, Knowledge Articles, etc.

In canvas-app formulas, use record references to work with polymorphic lookups. Because a record reference can refer to different tables, you can't know which fields are available at runtime when you write a formula. The Record.Field notation isn't available. These formulas need to adapt to the records that the app encounters when it runs.

The IsType function checks if a record reference refers to a specific table type. The function returns a Boolean TRUE or FALSE.

The AsType function treats a record reference as a specific table type, also called casting. You use the result as if it's a record of the table and use the Record.Field notation to access all the fields of that record. If the reference isn't of the specific type, an error occurs.

Use these functions together to first check the table type of a record and then treat it as a record of that type so the fields are available:

If( IsType( First( Accounts ).Owner, Users ),
    AsType( First( Accounts ).Owner, Users ).'Full Name',
    AsType( First( Accounts ).Owner, Teams ).'Team Name'
)

You need these functions only if you access the fields of a record reference. For example, you use record references in the Filter function without IsType or AsType:

Filter( Accounts, Owner = First( Users ) )

Similarly, you can use record references with the Patch function:

Patch( Accounts, First( Accounts ), { Owner: First( Teams ) } )

When you use these functions in a record context, such as within a Gallery or Edit form control, you might need the global disambiguation operator to reference the table type. For example, this formula works for a gallery that displays a list of contacts where Company Name is a Customer lookup:

If( IsType( ThisItem.'Company Name', Accounts ),
    AsType( ThisItem.'Company Name', Accounts ).'Account Name',
    AsType( ThisItem.'Company Name', Contacts ).'Full Name'
)

For both functions, specify the type by using the name of the data source connected to the table. For the formula to work, add a data source to the app for any types you want to check or cast. For example, add the Users table as a data source if you want to use IsType and AsType with an Owner lookup and records from that table. Add only the data sources you use in your app; you don't need to add all the tables that a lookup could reference.

If the record reference is blank, IsType returns FALSE, and AsType returns blank. All fields of a blank record are also blank.

Dynamic values

Important

A Dynamic value from a web API or the [ParseJSON function] needs to be converted to a specific typed value before you can use it in Power Fx. Here are some options:

  1. Implicitly type the field at the point you use it. For example, an object converts to a number if you use it with the + operator, if it can be converted to a number. This option can cause unexpected conversions and can't convert records and tables as a whole.
  2. Explicitly type each field individually with the Decimal, Text, DateTime, GUID, and other type constructor functions. This option is the most invasive to your formulas because you need to do each field separately.
  3. Explicitly type JSON with the second argument to the ParseJSON function. This option is easy and avoids needing the Dynamic value.
  4. Explicitly type a Dynamic value using the AsType function. You can also check the type before you try the conversion with the IsType function.

Syntax

AsType( RecordReference, TableType )

  • RecordReference - Required. A record reference, often a lookup field that refers to a record in any of several tables.
  • TableType - Required. The specific table to cast the record to.

AsType( DynamicValue, TypeSpecification )

  • DynamicValue - Required. A dynamic value from the ParseJSON function or API call.
  • TypeSpecification - Required. A type name or type specification you define with the Type function.

IsType( RecordReference, TableType )

  • RecordReference - Required. A record reference, often a lookup field that can refer to a record in any of multiple tables.
  • TableType - Required. The specific table to test for.

IsType( DynamicValue, TypeSpecification )

  • DynamicValue - Required. A dynamic value from the ParseJSON function or an API call.
  • TypeSpecification - Required. A type name or type specification defined with the Type function.

Examples

Record References

Understand record references and polymorphic lookups contains extensive examples.

  1. Create a blank canvas app for tablets.

  2. On the left pane, select Data > Add data, and then add Accounts and Contacts tables.

    Blank app with two data sources: accounts and contacts.

  3. On the left pane, select + (Insert) > Layout > Blank vertical gallery.

    Insert a gallery control with a blank vertical layout.

  4. Select Connect to data, and then select Contacts as the data source.

  5. Set the gallery layout to Title and subtitle.

    Open the layout picker from the properties pane.

    Set layout to Title and subtitle.

  6. In the Data pane, open the Title1 list, and then select Full Name.

    Set title value.

  7. Select the Subtitle1 label control.

    Set subtitle value.

  8. Set the Text property of Subtitle1 to this formula:

    If( IsBlank( ThisItem.'Company Name' ), "--",
        IsType( ThisItem.'Company Name', Accounts ),
            "Account: " & AsType( ThisItem.'Company Name', Accounts ).'Account Name',
        "Contact: " & AsType( ThisItem.'Company Name', Contacts ).'Full Name'
    )
    

    Screen is now complete showing accounts and contacts intermixed in the gallery.

    The subtitle in the gallery shows these values:

    • "--" if the 'Company Name' is blank.
    • "Account: " and the Account Name field from the Accounts table if the Company Name field refers to an account.
    • "Contact: " and the Full Name field from the Contacts table if the Company Name field refers to a contact.

    Your results can differ because the sample data can be modified to show more types of results.

Dynamic values

The following examples show a simple JSON record interpreted in various ways by ParseJSON, AsType, and IsType in the Pac CLI Power Fx REPL.

In this first example, no type information is provided to ParseJSON, so it returns a dynamic value.

>> Set( rec, ParseJSON( "{""a"":1}" ) )
rec: <Dynamic: Use Value, Text, Boolean, or other functions to establish the type>

The field is implicitly converted to a number when used in a numerical context.

>> 1 + rec.a
2

As an alternative, this example explicitly converts the record to a typed Power Fx record with the second argument to ParseJSON.

>> ParseJSON( "{""a"":1}", Type( {a: Number} ) )
{a:1}

And another alternative, this example explicitly converts the record to a typed Power Fx record using AsType.

>> AsType( ParseJSON( "{""a"":1}" ), Type( {a: Number} ) )
{a:1}

Finally, if you aren't sure, this example tests the type before converting it with the IsType function.

>> IsType( ParseJSON( "{""a"":1}" ), Type( {a: Number} ) )
true