Skip to main content Link Menu Expand (external link) Document Search Copy Copied

Dynamic Data Lists (DDLs)

DDLs are used to provide a dynamic dropdown list for an input. Unlike enums, DDLs are mainly there to help the user pick a value, not restrict which options are available. Users can choose to ignore the dropdown list and provide a value themselves.
Like enums, they can have separate text and value elements. This is useful in cases where the underlying value is not very user friendly to look at. For example, you could have user UUIDs as the values, and have their emails as the text. This would let users choose the input by finding the right email address, instead of having to find the UUID manually.
The other advantage of DDLs is the values can be fetched dynamically, using the user’s authentication. This means you can make an API call and use the result to generate the list.

  1. What are DDLs
  2. Making a DDL
    1. Operation from scratch
    2. Reuse an existing operation
    3. Adding a DDL to an input field
    4. Input dependent DDLs

What are DDLs

A DDL in a connector is simply another operation, but with a specific output structure, and is not visible in the operations list.

The operation must respond with an output structure like the following:

{
    "result": [
        {
            "text": "Bob",
            "value": 1234
        }
    ]
}

As you can see, the result property must be an array of objects with a text and value. The value can be either a string or a number, and is the value that gets stored as the input. The text must be a string and is what the user will see in the dropdown list.

For an operation to be recognised as a DDL, the name must either end in _ddl (like list_users_ddl), or have type: 'ddl' in the schema.js file.

// schema.js
module.exports = {
    type: 'ddl',
}

Making a DDL

Operation from scratch

To create an operation as a DDL, you setup the operation as you would normally, but rearrange the output to the correct structure.

The simplest way to do this is to use an afterSuccess function to modify the response from the API. In the following example, the operation will call the /users endpoint and extract the usernames and IDs from the result to create a DDL compatible response.

// model.js
module.exports = {
  url: '/users',

  afterSuccess: function(body) {
    return {
      result: body.results.map(user =>
        ({
          text: user.username,
          value: user.id
        })
      )
    }
  }
}

Reuse an existing operation

If you already have a list operation for the endpoint you are using, you can instead call that operation and reformat the result. This is usually a better way to make a DDL as you avoid code repetition.

If you already have a list_users operation, you could make a list_users_ddl like so:

// model.js
module.exports = async (params) => {
  const users = await falafel.myConnector.listUsers(params);
  return {
    result: users.map(user => ({
      text: user.username,
      value: user.id
    })),
  };
}

Adding a DDL to an input field

To add a DDL to an input field, you need to use the lookup property.

module.exports = {
  user_id: {
    type: 'string',
    description: 'The ID of the user',
    lookup: {
      url: '{{{step.ephemeral_url}}}',
      body: {
        message: 'list_users_ddl',
        auth_id: '{{{step.auth_id}}}',
        step_settings: {},
      },
    },
  },
}

Most simple lookup configurations will look like this. The message parameter is where you specify the name of the operation to call.

Input dependent DDLs

Sometimes, you might need to pass some user input into a DDL. For example, you might have chosen a postcode already, and the DDL for choosing an address needs to know the postcode in order to lookup the available options.

To do this, you would need to pass the postcode input to the DDL.

module.exports = {
  postcode: {
    type: 'string',
    required: true,
  },
  street_address: {
    type: 'string',
    title: 'Street Address',
    description: "Choose a street address",
    lookup: {
      url: '{{{step.ephemeral_url}}}',
      body: {
        message: 'list_street_addresses_ddl',
        auth_id: '{{{step.auth_id}}}',
        step_settings: {
          postcode: {
            type: 'string',
            value: '{{{properties.postcode}}}',
          }
        },
      },
    },
  },
}

In this example, we are using list_street_addresses_ddl as the DDL operation. We are also passing in an input called postcode, and getting the value for this from the input panel property postcode.

When a user has entered a postcode input such as SW1 1AA, they can click on the street_address field, and the DDL will call list_street_addresses_ddl operation with { postcode: 'SW1 1AA' } as the input.