Photo by on Unsplash

your contact details

Keep them up to date using a BOM logic

Christiaan Huizer
6 min readNov 7, 2023


Since we have various column types like email, URL, text and number and because we often collect contact information like an email address or a phone number via forms or modals, it is easy to see why we structure a table as we do below:

We got here because we have a modal (or a form) that looks a bit like the one below. You have all the contact details together, which makes data input easy. Everything related to one person is in one model.

Even if you add a time stamp using the Now() or thisRow.Created() function, it becomes a bit messy because all contact types are distributed over columns and you have to write a function that checks per column the latest input. This would look like something below for email only (so I am not speaking about all the others…)

getting the most recent update

To get a list of all most recent items per contact you have to make two more steps:

  • you name the filter part that outputs the values living in thisRow
  • you apply a SwitchIf() logic to define per column the values

It is a bit of work and in full transparency, I did not test this set up because I believe there is a smarter way to move forward.

Mixing ease of use with a strong BOM logic

In a BOM logic you have data ordered as you see below. The contact type and the contact details are distributed over only two columns. This makes filtering on contacts details per contact easy.

However when you add data to this specific table, it goes row per row, thus one by one. You select the contact type and you add the value. This is clumsy, time consuming and not necessary at all. See below.

the clumsy one by one data entrance

The best of two worlds

There is on the one hand the modal that is easy to use because you have all data per contact on one screen and we have a smart table that stores data in the most simple way: contact relates to contact type to contact value.

To get there we need to the magic of the button we click on to close the modal. In that button we have multiple actions. I focus on the distribution of the contact types and values.

The full function you find below. We first create a list with all values using ListCombine() and we filter out the blanks. This we name input.

Second and a bit more difficult, you have to relate each column to a contact type. I created for the contact types a dedicated table and I reference these items in my SwitchIf(). The result I renamed as: activeContactTypes.

So far it was all preparation, the action part you find below.

the action part

Here we count the inputs and we use this number (a virtual index) to add rows and per row a contact type and the contact details. The contact type is a named function, that is why you see in the screenshot a white chip followed by Nth(CurrentValue).

What follows is first a clean up. In case there is no contact or a contact but no values filled out, we delete the row and we return to the table DB Contact Details. The fall back option is the normal procedure, we execute the add row function and we end on the intended table.

This all together is no rocket science. I had to figure out this set up in a context that we have to keep track of contact details and the user of the document has normal


Getting the most recent value

I decided to work with relations on the canvas, the little controllers that relate to the display column of the table of your choice. Here we have two:

  • contacts
  • contact types (email, mobile phone etc)

Next, I added a column in the tabel DB Contact Details to output the most recent value related to the contact and the contact type.

Below the result:

filtering on the most recent

The code snippet applied on the canvas you see below. Besides I created a filter on the table view that gives all the details per contact (including the old ones).

[_relationDB-Contact-Details].IsBlank() and _cvsSearchContactDetails.IsBlank(),True())

Here you have one of advantages of the presented approach. You don’t have to show columns like LinkedIn, Facebook, etc. when that info is not present. You only see what you have.

is a row based solution.

function to show only the relevant and recent info per contact

Nota bene

When you add a column in your table that generates the modal, you have to update the code. It is something you have to think of. All the rest flows.

Two types of date references

In the context of an address I use a column named fromDate and it contains the date that marks the new address. This can be a future or a past date. The alternative is that you work with Now() or Created(). In the context of contact details, I often work with these two. The moment I get a new email address it is because the previous one no longer worked. It is a practical choice. Most important is that you can relate to a timestamped value.

This blog is part of small serie of 3 blogs in which I show the advantages of a BOM approach related to:

My name is Christiaan and blog about

. Since the summer of 2023 mainly about how to with AI to support organisations dealing with texts and templates. Why I focus on AI you can read here: ⤵️

I hope you enjoyed this article. If you have questions feel free to reach out. Though this article is for free, my work (including advice) won’t be, but there is always room for a chat to see what can be done. You find my (for free) contributions to the Coda Community and on Twitter.

Coda comes with a set of building blocks ー like pages for infinite depth, tables that talk to each other, and buttons that take action inside or outside your doc ーso anyone can make a doc as powerful as an app (source).

Not to forget: the Coda Community provides great insights for free once you add a sample doc.



Christiaan Huizer

I write about how to Coda . You find blogs for beginners and experienced makers. I publish about 1 / week. Welcome!