Implement a Data Provider
A data provider is a reference to a source of data. It’s implemented as a function within an Apex class.
To pull data into a view, bind the view to a data provider. To reference the data throughout a view, use an expression.
Apex Data Types
You can use these data types for input and output in Apex methods.
| Data Type | Description | Examples |
|---|---|---|
| Primitive | Boolean, Date, DateTime, Decimal, Double, Integer, Long, and String | - Primitive Input and Primitive Output - Primitive Input and List<Primitive> Output |
| sObject | A row of data declared using the SOAP API name of the object. Both standard and custom objects are supported. | - Standard Object Input and List Output - Custom Object Output - List<sObject> Output - Map with Contact List Output |
| Apex | An instance of an Apex class | Apex Class Output |
| Collection | A list, set, or map | - Standard Object Input and List Output -List<sObject> Output - Primitive Input and List<Primitive> Output - Map with Contact List Output |
Bind Apex Methods to Components
To bind a data provider to a component, follow this syntax for the definition value.
1apex__[ApexNamespace].ApexClassName.ApexMethodFor example:
1dataproviders:
2 yourData:
3 definition: "apex__MyDataProvider.getYourDataFromApexClass"The arguments passed to the Apex method are specified as properties to the data provider. The property key must match the name of the parameter in the Apex method signature.
Data Providers for Select and External Select Components
The Select component uses the dataproviders property to bind a data provider to the view.
To create a data provider for a Select component, construct a List<Slack.Option> or List<Slack.OptionGroup> for your view definition.
The External Select component uses the datasource property to bind a data provider to the view. For the External Select component, your Apex methods must follow certain method signature restrictions.
- Must have a String value as the first parameter in addition to any other parameters already present.
- Must return
Slack.OptionDataResponse. ConstructSlack.OptionDataResponsewithList<Slack.OptionGroup>orList<Slack.Option>. All items in the sameSlack.OptionDataResponsemust be of the same type.
Constructing a Slack.OptionDataResponse with a combination of Slack.Option and Slack.OptionGroup isn’t supported.
Important
The optional value parameter provides the input string entered into the select component that’s used to perform the lookup. The value you provide preselects an option from the options identifier or from your data provider.
1components:
2 - definition: select
3 properties:
4 name: "StageName"
5 value: "Prospecting"
6 placeholder: "Select a stage."
7 options:
8 - identifier: "Prospecting"
9 label: "Prospecting"
10 - identifier: "Qualification"
11 label: "Qualification"Examples
These examples show you how to create a data provider with Apex data types.
Primitive Input and Primitive Output
Apex method:
1public class EchoExample {
2 public static String echo(String echoStr) {
3 return echoStr;
4 }
5}View:
1description: "This simple view contains an Apex echo data provider"
2schema:
3 properties:
4 title:
5 type: string
6 defaultValue: "Echo ApexDataProvider"
7 myString:
8 type: string
9 default: "Hello, World!"
10dataproviders:
11 echoStr:
12 definition: "apex__EchoExample.echo"
13 properties:
14 echoStr: "{!view.properties.myString}"
15components:
16 - definition: modal
17 properties:
18 title: "{!view.properties.title}"
19 components:
20 - definition: section
21 properties:
22 text: "{!echoStr}" # will render Hello, World!Standard Object Input and List Output
Apex method:
1public class ObjectInputListOutputExample {
2 public static List<Contact> getAccountContacts(Account acct) {
3 List<Contact> contacts = [
4 SELECT Id, Name, Title, Phone, Email
5 FROM Contact
6 WHERE AccountId = :acct.Id
7 WITH SECURITY_ENFORCED
8 LIMIT 10
9 ];
10
11 return contacts;
12 }
13}View:
1description: "This list view contains an Apex Contact list data provider for an Account"
2schema:
3 properties:
4 title:
5 type: string
6 defaultValue: "Account Contacts ApexDataProvider"
7 accountId:
8 type: string
9 defaultValue: "001xx000003GYQRAA4"
10dataproviders:
11 contacts:
12 definition: "apex__ObjectInputListOutputExample.getAccountContacts"
13 properties:
14 acct:
15 Id: "{!view.properties.accountId}"
16components:
17 - definition: modal
18 properties:
19 title: "{!view.properties.title}"
20 components:
21 - definition: header
22 properties:
23 text: "My Contacts"
24 - definition: iteration
25 properties:
26 foreach: "{!contacts}"
27 foritem: "contact"
28 components:
29 - definition: divider
30 - definition: section
31 properties:
32 text: "{!contact.Name}"
33 - definition: section
34 properties:
35 text:
36 text: "*Id:* {!contact.Id}"
37 type: mrkdwn
38 - definition: section
39 properties:
40 text:
41 text: "*Title:* {!contact.Title}"
42 type: mrkdwn
43 - definition: section
44 properties:
45 text:
46 text: "*Phone:* {!contact.Phone}"
47 type: mrkdwn
48 - definition: section
49 properties:
50 text:
51 text: "*Email:* {!contact.Email}"
52 type: mrkdwnApex Class Output
Apex method:
1public class ClassOutputExample {
2 public static TestClass getApexClass() {
3 return new TestClass();
4 }
5}
6
7// User-defined Apex class
8public class TestClass {
9 public final String myString = 'Hello from TestClass class!';
10}View:
1description: "This simple view contains an Apex user type data provider"
2schema:
3 properties:
4 title:
5 type: string
6 defaultValue: "UserType ApexDataProvider"
7dataproviders:
8 apexClass:
9 definition: "apex__ClassOutputExample.getApexClass"
10components:
11 - definition: modal
12 properties:
13 title: "{!view.properties.title}"
14 components:
15 - definition: section
16 properties:
17 text: "{!apexClass.myString}"Custom Object Output
Apex method:
1public class CutomObjectOutputExample {
2 public static MyCustomObject__c getCustomObject(Id objectId) {
3 MyCustomObject__c customObject = [
4 SELECT Id, Name, CustomTextField__c, CustomDateField__c, CustomNumberField__c
5 FROM MyCustomObject__c
6 WHERE Id = :objectId
7 WITH SECURITY_ENFORCED
8 ];
9
10 return customObject;
11 }
12}View:
1description: "This simple view contains an Apex single custom object data provider"
2schema:
3 properties:
4 title:
5 type: string
6 defaultValue: "CustomObject ApexDataProvider"
7 objectId:
8 type: string
9 defaultValue: "a00xx000000boMTAAY"
10dataproviders:
11 customobject:
12 definition: "apex__CutomObjectOutputExample.getCustomObject"
13 properties:
14 objectId: "{!view.properties.objectId}"
15components:
16 - definition: modal
17 properties:
18 title: "{!view.properties.title}"
19 components:
20 - definition: header
21 properties:
22 text: "CustomObject: {!view.properties.objectId}"
23 - definition: section
24 properties:
25 text: "{!customobject.Name}"
26 - definition: section
27 properties:
28 text:
29 text: "*Id:* {!customobject.Id}"
30 type: mrkdwn
31 - definition: section
32 properties:
33 text:
34 text: "*Custom Text Field:* {!customobject.CustomTextField__c}"
35 type: mrkdwn
36 - definition: section
37 properties:
38 text:
39 text: "*Custom Date Field:* {!customobject.CustomDateField__c}"
40 type: mrkdwn
41 - definition: section
42 properties:
43 text:
44 text: "*Custom Number Field:* {!customobject.CustomNumberField__c}"
45 type: mrkdwnsObject List Output
Apex method:
1public class ListOutputExample {
2 public static List<Contact> getContactList() {
3 List<Contact> contacts = [
4 SELECT Id, Name, Title, Phone, Email
5 FROM Contact
6 WITH SECURITY_ENFORCED
7 LIMIT 10
8 ];
9
10 return contacts;
11 }
12}View:
1description: "This is a simple list view containing an Apex contact list data provider"
2schema:
3 properties:
4 title:
5 type: string
6 defaultValue: "Contacts ApexDataProvider"
7dataproviders:
8 contacts:
9 definition: "apex__ListOutputExample.getContactList"
10components:
11 - definition: modal
12 properties:
13 title: "{!view.properties.title}"
14 components:
15 - definition: header
16 properties:
17 text: "My Contacts"
18 - definition: iteration
19 properties:
20 foreach: "{!contacts}"
21 foritem: "contact"
22 components:
23 - definition: divider
24 - definition: section
25 properties:
26 text: "{!contact.Name}"
27 - definition: section
28 properties:
29 text:
30 text: "*Id:* {!contact.Id}"
31 type: mrkdwn
32 - definition: section
33 properties:
34 text:
35 text: "*Title:* {!contact.Title}"
36 type: mrkdwn
37 - definition: section
38 properties:
39 text:
40 text: "*Phone:* {!contact.Phone}"
41 type: mrkdwn
42 - definition: section
43 properties:
44 text:
45 text: "*Email:* {!contact.Email}"
46 type: mrkdwnPrimitive Input and Primitive List Output
Apex method:
1public class StringListExample {
2 public static String[] echoMultiple(String string1, String string2, String string3) {
3 List<String> myList = new List<String>();
4 myList.add(string1);
5 myList.add(string2);
6 myList.add(string3);
7 return myList;
8 }
9}View:
1description: "This is a simple list view containing an Apex echo list data provider"
2schema:
3 properties:
4 title:
5 type: string
6 defaultValue: "EchoMultiple ApexDataProvider"
7 string1:
8 type: string
9 required: true
10 string2:
11 type: string
12 required: true
13 string3:
14 type: string
15 required: true
16dataproviders:
17 echoStrings:
18 definition: "apex__StringListExample.echoMultiple"
19 properties:
20 string1: "{!view.properties.string1}"
21 string2: "{!view.properties.string2}"
22 string3: "{!view.properties.string3}"
23components:
24 - definition: modal
25 properties:
26 title: "{!view.properties.title}"
27 components:
28 - definition: iteration # iterate through list of strings
29 properties:
30 foreach: "{!echoStrings}"
31 foritem: "echoStr"
32 components:
33 - definition: section
34 properties:
35 text: "{!echoStr}"Map with Contact List Output
Apex method:
1public class MapContactListExample {
2 publicstatic Map<Id, List<Contact>> getAccountContactMap() {
3 List<Contact> contacts = [
4 SELECT Id, Name, Title, Phone, Email, AccountId
5 FROM Contact
6 WITH SECURITY_ENFORCED
7 LIMIT 10
8 ];
9 Map<Id, List<Contact>> contactMap = new Map<Id, List<Contact>>();
10 for (Contact contact : contacts) {
11 Id acctId = contact.AccountId;
12 if (!contactMap.containsKey(acctId)) {
13 contactMap.put(acctId, new List<Contact>());
14 }
15 contactMap.get(acctId).add(contact);
16 }
17
18 return contactMap;
19 }
20}View:
1description: "This is a simple list view containing an Apex account contact map data provider"
2schema:
3 properties:
4 title:
5 type: string
6 defaultValue: "Account Contacts ApexDataProvider"
7dataproviders:
8 contacts:
9 definition: "apex__MapContactListExample.getAccountContactMap"
10components:
11 - definition: modal
12 properties:
13 title: "{!view.properties.title}"
14 components:
15 - definition: header
16 properties:
17 text: "My Contacts for 001xx000003GYQRAA4"
18 - definition: iteration
19 properties:
20 foreach: "{!contacts.001xx000003GYQRAA4}"
21 foritem: "contact"
22 components:
23 - definition: divider
24 - definition: section
25 properties:
26 text: "{!contact.Name}"
27 - definition: section
28 properties:
29 text:
30 text: "*Id:* {!contact.Id}"
31 type: mrkdwn
32 - definition: section
33 properties:
34 text:
35 text: "*Title:* {!contact.Title}"
36 type: mrkdwn
37 - definition: section
38 properties:
39 text:
40 text: "*Phone:* {!contact.Phone}"
41 type: mrkdwn
42 - definition: section
43 properties:
44 text:
45 text: "*Email:* {!contact.Email}"
46 type: mrkdwnThis example is from view_contact.view in the sample app.
Tip
External Select
Apex data provider using List<Slack.Option> and returning Slack.OptionDataResponse:
1global class AccountDataProvider {
2 global static Slack.OptionDataResponse getAccountsByName(String value) {
3 String name = '%'+ value + '%';
4 List<Account> accounts = [
5 SELECT Id, Name
6 FROM Account
7 WHERE Name LIKE :name
8 WITH SECURITY_ENFORCED
9 LIMIT 10
10 ];
11 System.debug('retrieved accounts');
12 List<Slack.Option> accountOptions = new List<Slack.Option>();
13 for(Account account: accounts) {
14 Slack.Option option = new Slack.Option(account.Name, account.Id);
15 System.debug(option.getText());
16 accountOptions.add(option);
17 }
18 return new Slack.OptionDataResponse(accountOptions);
19 }
20}Apex data provider using List<Slack.OptionGroup> and returning Slack.OptionDataResponse:
1global class ContactDataProvider {
2 global static Slack.OptionDataResponse getContactGroupsByName(String value) {
3 String name = '%'+ value + '%';
4 List<Contact> contacts = [
5 SELECT Name, Id, AccountId, Account.name
6 FROM Contact
7 WHERE Name LIKE :name
8 LIMIT 10
9 ];
10 Map<Id, List<Slack.Option>> contactsByAccount = new Map<Id, List<Slack.Option>>();
11 Map<Id, String> accountNames = new Map<Id,String>();
12 for(Contact contact: contacts) {
13 List<Slack.Option> options = contactsByAccount.get(contact.AccountId);
14 Slack.Option currentOption = new Slack.Option(contact.name, contact.id);
15 if (options == null) {
16 List<Slack.Option> newList = new List<Slack.Option>();
17 newList.add(currentOption);
18 contactsByAccount.put(contact.AccountId, newList);
19 accountNames.put(contact.AccountId, contact.Account.name);
20 } else {
21 options.add(currentOption);
22 }
23 }
24 List<Slack.OptionGroup> contactOptionGroups = new List<Slack.OptionGroup>();
25 for(Id key : contactsByAccount.keySet()) {
26 String accountName = accountNames.get(key);
27 System.debug(key);
28 Slack.OptionGroup optionGroup = new Slack.OptionGroup(accountName, contactsByAccount.get(key));
29 System.debug(optionGroup.getLabel());
30 contactOptionGroups.add(optionGroup);
31 }
32 return new Slack.OptionDataResponse(contactOptionGroups);
33 }
34}View:
1description: "View with external select examples."
2components:
3 - definition: modal
4 properties:
5 title: "External Select"
6 components:
7 - definition: section
8 properties:
9 text: "Select an Account"
10 - definition: actions
11 name: "external_select_accounts"
12 components:
13 - definition: externalSelect
14 properties:
15 placeholder: "Look up an account by name"
16 name: "account_lookup"
17 datasource:
18 definition: "apex__AccountDataProvider.getAccountsByName"
19 - definition: section
20 properties:
21 text: "Select a Contact"
22 - definition: actions
23 name: "external_select_contacts"
24 components:
25 - definition: externalSelect
26 properties:
27 placeholder: "Look up a Contact by name"
28 name: "contact_lookup"
29 datasource:
30 definition: "apex__ContactDataProvider.getContactGroupsByName"This example is from create_opportunity.view in the sample app.
Tip
Beta Feature