Skip to Content

Conditional container

Conditional container sends one group of blocks when a JavaScript expression is yes, and the other group when it is no. Drag it from Containers. Put the yes blocks in the first area and the fallback blocks in the second. The canvas reads “If condition … is correct, then” and “Otherwise”.

The sample sign-in email uses it for the logo, with the condition config.logo.

Conditional container selected in the email layout

Conditional container with a single Condition field

FieldWhat it changes
ConditionA JavaScript expression. Yes sends the first area. No sends the second. Do not wrap it in {{ }}.

There is no separate color or padding on this block. Style the blocks you put inside it.

Where the names come from

The names are the same data as placeholders. Open View context, or the braces button on the builder toolbar. Each name at the top of that list is a variable. A placeholder {{customer.name}} is the expression customer.name here. Drop the braces.

Preview fills the variables with the sample booking. The email that is sent uses the customer and appointment on that send. A sign-in message does not have addons or dateTime. Use only names that appear for that message.

Nested fields use a dot: customer.name, service.price, config.logo, dateTime.isTomorrow.

Yes or no

Hacado does not look for the words true or false. It asks whether the result counts as yes in JavaScript.

ResultCounts as
A non-empty piece of text, such as a logo URL or a nameYes
A number other than 0, including a lengthYes
true, such as confirmed or dateTime.isTomorrowYes
false, 0, or ""No
A missing valueNo
Any list, even an empty oneYes. An empty list is still a list. Test addons.length when you mean “has at least one”.
Any object, such as discount or memberYes, when that object is present

These are the usual yes/no checks:

ExpressionYes when
config.logoA logo is set
!config.logoNo logo
customer.emailThe customer has an email
member && member.jobTitleThe staff member has a job title
member?.jobTitleSame check. ?. stays no when member is missing, instead of breaking the expression
discountThe booking has a discount
confirmedThe appointment is confirmed
pendingIt is still a request
declinedIt was declined
canceledIt was canceled
noShowIt was a no-show
dateTime.isTomorrowThe appointment is tomorrow in the business time zone
meetingInformationThe appointment has a video meeting
addons.lengthThere is at least one add-on
packageUsage && packageUsage.isPackageAppointmentA package covers this appointment

confirmed, pending, declined, canceled, and noShow are already yes/no. You do not have to compare the status text yourself.

Comparisons

Compare the raw value, not the formatted string. service.price is the number 50. service.priceFormatted is text such as $50.00, and that text changes with currency.

ExpressionYes when
service.price > 0The service has a price
service.price >= 100The price is 100 or more
totalAmountLeftToPay > 0Something is still due
totalAmountPaid === 0Nothing has been paid
addons.length > 1More than one add-on
duration.hours >= 1The appointment is at least one hour
dateTime.hour >= 12The appointment is at noon or later
service.name === "Demo service"The service name is exactly that text
status === "confirmed"Same answer as confirmed

=== is an exact match. !== is not that value. > , < , >= , and <= are for numbers. Text matched with === is case-sensitive: "Demo service" is not "demo service".

A formatted date is a poor comparison. dateTime.full changes with language and time zone. Prefer dateTime.isTomorrow, dateTime.hour, or the status flags.

Combine tests

&& means both. || means either. ! flips the answer.

ExpressionYes when
confirmed && addons.lengthConfirmed, and there is at least one add-on
!canceled && !declinedNot canceled and not declined
discount && discount.discountAmount > 0A discount took money off the total
payments.some(payment => payment.isDeposit)One of the payments is a deposit
payments.some(payment => payment.isGiftCard)One of the payments is a gift card

|| means either side may be yes. A request that should also match a confirmed appointment is:

pending || confirmed

some walks a list and is yes when any item matches. Other payment flags on each item are isOnline, isCash, isInPersonCard, isTips, isPayment, isRescheduleFee, and isCancellationFee.

When the expression fails

A path that does not exist, such as addons.length on a sign-in email, does not send the first area. The fallback area is sent. The same happens for a typo, or for member.jobTitle when there is no member. Use member?.jobTitle, or member && member.jobTitle, when that value is only sometimes there.

Good to know

  • The first area is the yes result. The second area is the no result. Leave the second area empty when a no result should send nothing.
  • Put a Loop container in the yes area when the rows should appear only if the list has items. The loop’s own Value is documented on Loop container.