Accept input with parameters¶
The primary mechanism for passing data from the user or document into your Pack is via parameters. You define the parameters in your code and the user fills them with values when they use your Pack. The same parameter mechanism is used by formulas, actions, and sync tables.
Using parameters¶
In the formula editor parameters are entered as comma-separated values, while in the action dialog or sync table side panel they presented as input boxes.
Defining parameters¶
The parameters
property of a formula contains the array of parameter definitions, each one containing information about the parameter. The helper function makeParameter()
is used to create these definitions, and a type
, name
, and description
are required.
coda.makeParameter({
type: coda.ParameterType.String,
name: "type",
description: "The type of cookie.",
})
See ParamDef
for the full set of properties you can define for a parameter.
Accessing parameter values¶
At runtime, the values set by the user are passed to the formula's execute
function as the first argument, bundled up as an array.
pack.addFormula({
// ...
parameters: [
coda.makeParameter({
type: coda.ParameterType.String,
name: "type",
description: "The type of cookie.",
}),
coda.makeParameter({
type: coda.ParameterType.Number,
name: "num",
description: "How many cookies.",
}),
],
// ...
execute: async function ([type, num], context) {
// ...
},
});
The order that you define the parameters determines the order they are passed into the execute
function. The names of the parameters don't need to match the variable names you use for them in the execute
function, but it's usually more readable to keep them the same.
Array destructuring
In the code above, and across our other samples, we typically use array destructuring to pull values out of the parameter array and assign them to variables. You could alternatively do that within the body of the execute
function:
execute: async function (parameters, context) {
let word = parameters[0];
let count = parameters[1];
},
Optional parameters¶
By default all parameters you define are required. To make a parameter optional simply add optional: true
to your parameter definition. Optional parameters are shown to the user but not required in order for the formula to execute. Optional parameters must be defined after all of the required parameters, and like required parameters their order is reflected in the Coda formula editor and the array of values passed to the execute
function.
pack.addFormula({
// ...
parameters: [
coda.makeParameter({
type: coda.ParameterType.String,
name: "name",
description: "The person's name.",
}),
coda.makeParameter({
type: coda.ParameterType.String,
name: "suffix",
description: "A suffix, like 'MD' or 'Jr'.",
optional: true,
}),
],
// ...
execute: async function ([name, suffix], context) {
// ...
},
});
Optional parameters that have not been set by the user will default to the JavaScript value undefined
in your execute
function. When you initialize your parameter variables in the execute
function you can assign a default value that will get used when the parameter has not been explicitly set by the user.
import * as coda from "@codahq/packs-sdk";
export const pack = coda.newPack();
// Formats text to look like screaming. For example, "Hello" => "HELLO!!!".
pack.addFormula({
name: "Scream",
description: "Make text uppercase and add exclamation points.",
parameters: [
coda.makeParameter({
type: coda.ParameterType.String,
name: "text",
description: "The text to scream.",
}),
coda.makeParameter({
type: coda.ParameterType.Number,
name: "volume",
description: "The number of exclamation points to add.",
optional: true,
}),
coda.makeParameter({
type: coda.ParameterType.String,
name: "character",
description: "The character to repeat.",
optional: true,
}),
],
resultType: coda.ValueType.String,
execute: async function ([text, volume = 3, character = "!"], context) {
return text.toUpperCase() + character.repeat(volume);
},
});
When using a formula with optional parameters, the user may choose to set those parameters by name, instead of by position. This can be useful when they want to skip over some optional parameters that appear earlier in the list.
Scream("What is this", character: "?")
In this case the text
and character
parameters would be set, but the volume
parameter would be undefined, and therefore use it's default value of 3
.
Suggested values¶
As a convenience to users of your Pack, you can provide a suggested value for a parameter. When they use your formula the default will be pre-populated in the formula editor, action dialog, etc. The user is then free to edit or replace it this value.
To add a suggested value to a parameter set the field defaultValue
to the value you'd like to use. The suggested value must be of the same type as the parameter, for example a number parameter must have a number as it's suggested default value.
coda.makeParameter({
type: coda.ParameterType.Number,
name: "days",
description: "How many days of data to fetch.",
defaultValue: 30,
})
Currently suggested values are only used for required parameters, and setting them for optional parameters has no effect.
Accepting multiple values¶
For some formulas you may want to allow the user to enter multiple values for a parameter. You could use an array parameter for this case but a more user-friendly approach may be to use variable argument (vararg) parameters. These are parameters that you allow the user to repeat as many times as needed.
Foo(List("A", "B", "C")) # A string array parameter.
Foo("A", "B", "C") # A string variable argument parameter.
They are defined using the varargParameters
property and accept the same parameter objects. The values set by the user are passed in to the execute
just like normal parameters, only there is an unknown number of them. The easiest way to access them is by using JavaScript's "rest" syntax, which captures the remaining values into an array.
pack.addFormula({
// ...
parameters: [
coda.makeParameter({
type: coda.ParameterType.String,
name: "name",
description: "The person's name.",
}),
],
varargParameters: [
coda.makeParameter({
type: coda.ParameterType.String,
name: "nickname",
description: "A nickname for the person.",
}),
],
// ...
execute: async function ([name, ...nicknames], context) {
// ...
},
});
There are some important differences between vararg parameters and standard parameters:
- They appear at the end of the formula, after all standard parameters.
- Unlike standard parameters they are optional by default, and cannot by made required.
- You can't provide a default value, since the user must always enter an explicit value.
- You can have more than one, but if so the user is required to enter complete sets of values. For example, if you have two vararg parameters
a
andb
, the user can't provide a value fora
without also providing a value forb
. These pairs of parameters can then be repeated multiple times:Foo("a1", "b1", "a2", "b2")
.
Not available in actions builder or sync table settings
At the moment, vararg parameters can only be set in the formula editor. In the action dialog users can switch from the default structured builder to the formula editor, but there is no way to set them for sync tables.
import * as coda from "@codahq/packs-sdk";
export const pack = coda.newPack();
// Takes an unknown number of steps and labels and outputs a simple diagram.
// Example: Steps("Idea", "Experiment", "Prototype", "Refine", "Product")
// Result: Idea --Experiment--> Prototype --Refine--> Product
pack.addFormula({
name: "Steps",
description: "Draws a simple step diagram using text.",
parameters: [
coda.makeParameter({
type: coda.ParameterType.String,
name: "start",
description: "The starting step.",
}),
],
varargParameters: [
coda.makeParameter({
type: coda.ParameterType.String,
name: "label",
description: "The label for the arrow.",
}),
coda.makeParameter({
type: coda.ParameterType.String,
name: "step",
description: "The next step.",
}),
],
resultType: coda.ValueType.String,
execute: async function ([start, ...varargs], context) {
let result = start;
while (varargs.length > 0) {
let label; let step;
// Pull the first set of varargs off the list, and leave the rest.
[label, step, ...varargs] = varargs;
result += ` --${label}--> ${step}`;
}
return result;
},
});
Autocomplete¶
If you have a parameter that accepts a limited set of values it's usually best to provide those options using autocomplete. See the Autocomplete guide for more information.
Reusing parameters¶
It's often the case that many formulas in a Pack use the same parameter. For example, the Google Calendar Pack has many formulas have a parameter for the calendar to operate on. Rather than redefine the same parameter for each formula, it can be more efficient to define the shared parameter once outside of a formula and then reuse it multiple times.
const ProjectParam = coda.makeParameter({
type: coda.ParameterType.String,
name: "projectId",
description: "The ID of the project.",
});
pack.addFormula({
name: "GetProject",
description: "Get a project.",
parameters: [
ProjectParam,
],
// ...
});
pack.addFormula({
name: "GetTask",
description: "Get a task within a project.",
parameters: [
ProjectParam,
coda.makeParameter({
type: coda.ParameterType.String,
name: "taskId",
description: "The ID of the task.",
}),
],
// ...
});
Date range parameters¶
Parameters of the type DateArray
are often used for date ranges, with the first date representing the start of the range and the second date representing the end. When a DateArray
parameter is used in an action or sync table the the input box displays a date range picker to make it easier for the user to select a range.
These parameters also support a special set of suggested values that represent date ranges relative to the current date. These are available in the PrecannedDateRange
enumeration.
coda.makeParameter({
type: coda.ParameterType.DateArray,
name: "dateRange",
description: "The date range over which data should be fetched.",
defaultValue: coda.PrecannedDateRange.Last30Days,
})