Skip to main content

⚗️ Lesson 4.2: Practical Formula Patterns (with Optional Deep-Dive)

This is your formula cookbook. Every recipe below is copy-paste ready, with a plain-English explanation of what it does and how to adapt it. The goal is not to memorize any of them — it's to build a little library you can reach into whenever your workspace needs a computed touch. Copy, adapt, move on.

📚 What You'll Learn

By the end of this lesson, you will be able to:

  • Copy and adapt everyday formula recipes: days-until-due, overdue flag, auto status label
  • Build a text-based progress bar from a rollup percentage
  • Create conditional indicators (🔴🟡🟢) and combined text labels
  • Use formatDate and dateBetween for friendly dates and durations
  • (Optional) Peek at lists — map, filter, find — and let() for readable formulas

⏱️ Estimated Time: 65 minutes

🎯 Project: Add two recipes of your choice to your system — a progress bar and a status/indicator formula.

In This Lesson

How to Use This Cookbook

Treat these like kitchen recipes. You don't reinvent bread every morning — you follow a recipe and tweak the salt. Formulas are the same: the community and Notion's own docs are full of proven patterns, and the skill that matters is adapting one to your property names, not composing from scratch.

For each recipe below:

  1. Read the plain-English line to see what it does.
  2. Copy the code into a Formula property.
  3. Swap the property names (prop("Due"), prop("Done"), etc.) for whatever yours are called — use autocomplete so they're spelled right.
  4. Check the result and adjust the words/emoji to taste.

🧠 Mindset

Copying formulas is not cheating — it's literacy. Experienced Notion users keep a personal "formula stash" and paste from it constantly. If a recipe looks intimidating, don't stare at the whole thing; find the prop("...") pieces, recognize the if, and trust the rest. You are reading, not memorizing.

Dates & Deadlines Recipes

🗓️ Days until due (or days overdue)

Shows how many days until the Due date; negative means overdue.

dateBetween(prop("Due"), now(), "days")

A friendlier, wordier version that handles a missing date:

if(empty(prop("Due")),
   "No due date",
   format(dateBetween(prop("Due"), now(), "days")) + " days left")

⚠️ Overdue flag

Marks unfinished tasks whose Due date has passed.

if(prop("Done"), "",
   if(prop("Due") < now(), "⚠️ Overdue", ""))

🔁 Next review date (spaced-repetition-ish)

Adds an interval (in days) to the last reviewed date to suggest when to review again.

dateAdd(prop("Last reviewed"), prop("Interval (days)"), "days")

Pair it with a "due for review?" check:

if(dateAdd(prop("Last reviewed"), prop("Interval (days)"), "days") <= now(),
   "📚 Review now", "✅ Up to date")

⏱️ Duration between two dates

How long a project ran, in days.

if(empty(prop("Start")) or empty(prop("End")),
   "",
   format(dateBetween(prop("End"), prop("Start"), "days")) + " days")

💡 formatDate niceties

formatDate() shows a date exactly how you like. A few tokens: formatDate(prop("Due"), "MMM D") → Oct 12; "dddd" → Monday; "YYYY-MM-DD" → 2026-10-12. Great for a clean "due day" column that reads like plain English instead of a full timestamp.

Status & Indicator Recipes

🏷️ Auto status label

One clear label combining Done, missing date, overdue, and on-track.

ifs(
   prop("Done"), "✅ Done",
   empty(prop("Due")), "🗓️ No date",
   prop("Due") < now(), "⚠️ Overdue",
   "🟢 On track"
)

🔴🟡🟢 Conditional emoji indicator

A traffic light from a number (e.g. days left or a priority score).

ifs(
   dateBetween(prop("Due"), now(), "days") < 0, "🔴",
   dateBetween(prop("Due"), now(), "days") <= 2, "🟡",
   "🟢"
)

Read it: overdue → red, due within two days → yellow, otherwise green. Swap the numbers to taste.

⭐ Priority stars from a number

Turns a 1–3 priority number into stars.

ifs(
   prop("Priority") >= 3, "⭐⭐⭐",
   prop("Priority") == 2, "⭐⭐",
   "⭐"
)

✅ Indicators shine in Board & Gallery views

A single-emoji indicator formula reads beautifully as the first thing on a board card or gallery tile — instant visual triage without opening anything. Put your 🔴🟡🟢 formula near the top of the card's visible properties.

Progress Bar from a Rollup

Remember the "% complete" rollup from Lesson 3.5? A formula can turn that number into a little visual bar made of block characters — no images, no add-ons. Here's the everyday pattern:

// prop("% complete") is a rollup returning 0–1 (a percent)
// Build a 10-slot bar of filled/empty squares
slice("🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩", 0, round(prop("% complete") * 10) * 2)
  + slice("⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜", 0, (10 - round(prop("% complete") * 10)) * 2)
  + " " + format(round(prop("% complete") * 100)) + "%"

In plain English: take up to ten 🟩 for the completed share, fill the rest with ⬜, and tack the percentage on the end. A project that's 30% done shows 🟩🟩🟩⬜⬜⬜⬜⬜⬜⬜ 30%. (The * 2 is because each emoji square counts as two characters to slice.)

💡 If your percent is 0–100 instead of 0–1

Rollup percentages usually come through as a fraction (0.3 = 30%). If yours is already 0–100, drop the * 10 tricks and divide by 10 instead, or simply divide your value by 100 first so the rest of the recipe works unchanged. When in doubt, temporarily show format(prop("% complete")) to see the raw number.

Prefer something shorter? A minimalist bar:

let(pct, round(prop("% complete") * 10),
   slice("██████████", 0, pct) + slice("░░░░░░░░░░", 0, 10 - pct))

(This one uses let() to name the value once — covered in the optional section below.)

Text & Combining Recipes

🧩 Combine text (full name / label)

Glue several properties into one readable string.

prop("First") + " " + prop("Last")

// with a fallback if a piece is blank:
if(empty(prop("Nickname")), prop("First"), prop("Nickname"))

🏷️ Label with a number folded in

Remember to format() the number before joining it to words.

prop("Project") + " — " + format(prop("Task count")) + " tasks"

✂️ Trim a long title for cards

Show the first 40 characters with an ellipsis if longer.

if(length(prop("Task")) > 40,
   slice(prop("Task"), 0, 40) + "…",
   prop("Task"))

🔎 Tag detector

Flag rows whose title mentions something.

if(prop("Task").lower().contains("call"), "📞", "")

⚠️ Copy, adapt, don't memorize

None of these are worth memorizing. What's worth keeping is the habit: find a recipe, paste it, swap the property names, verify the result. If you internalize only prop(), if/ifs, and format(), you can adapt anything in this cookbook.

🌟 Going Further (optional)

This whole section is optional. Everything above is enough for a superb workspace. This is the deep end — lists and cleaner structure — for when you're curious and comfortable. Skip it with zero guilt; come back when a real need shows up.

Lists (arrays): map, filter, find

A relation hands your formula a list of related rows, and Formulas 2.0 can work through that list. Three verbs do most of the work:

  • map — transform each item into something (make a new list).
  • filter — keep only items that pass a test.
  • find — return the first item that passes a test.

Inside these, current refers to the item being looked at. For example, count a project's open tasks directly in a formula (rather than a rollup):

prop("Tasks")
   .filter(not current.prop("Done"))
   .length()
// keep the tasks whose Done is false, then count them

Or list the names of every related task, comma-separated:

prop("Tasks").map(current.prop("Name")).join(", ")

Naming values with let() and lets()

When a value appears several times (like our percent bar), let() lets you name it once so the formula reads cleanly and computes it a single time:

let(days, dateBetween(prop("Due"), now(), "days"),
   ifs(days < 0, "🔴 " + format(-days) + "d overdue",
       days == 0, "🟡 Due today",
       "🟢 " + format(days) + "d left"))

lets() is the same idea for naming several values at once. These don't add power so much as readability — which, once formulas get long, is its own kind of power.

💡 When the formula gets truly gnarly

If a formula grows past what's comfortable, that's often a sign the job belongs to a rollup, a button, or (for teams) an automation instead. AI add-on Notion AI can also draft a formula from a plain-English description if you have the paid add-on — a handy starting point you then read and adjust. Don't out-clever yourself; the simplest thing that works wins.

🎯 Project: Add Two Recipes

Pick two recipes and add them to your system — one progress bar and one status/indicator formula. Both work on the Free plan. Building them cements the copy-adapt-verify habit that makes formulas painless forever.

🏋️ A progress bar + an indicator

Objective: Two working formula properties that read your real data and display something genuinely useful at a glance.

Instructions (about 25 minutes):

  1. (3 min) Decide where each goes. The progress bar fits best on Projects (using the "% complete" rollup); the indicator fits on Tasks (using Due/Done).
  2. (8 min) On Projects, add a Formula property "Progress" and paste the progress-bar recipe. Swap prop("% complete") for your rollup's exact name. Confirm the bar length matches the percentage.
  3. (8 min) On Tasks, add a Formula property "Signal" and paste the 🔴🟡🟢 indicator (or the auto status label). Swap in your Due/Done names.
  4. (3 min) Add both formula columns to a Board or Gallery view so the visual pops on the cards.
  5. (3 min) Change a task's date/status and watch both the indicator and the project's progress bar react live.
💡 Hint — the two starter recipes
// Progress bar (Projects) — "% complete" is a 0–1 rollup
slice("🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩", 0, round(prop("% complete") * 10) * 2)
  + slice("⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜", 0, (10 - round(prop("% complete") * 10)) * 2)
  + " " + format(round(prop("% complete") * 100)) + "%"

// Indicator (Tasks)
ifs(
   prop("Done"), "✅",
   empty(prop("Due")), "⚪",
   dateBetween(prop("Due"), now(), "days") < 0, "🔴",
   dateBetween(prop("Due"), now(), "days") <= 2, "🟡",
   "🟢"
)

Red error? Check property names match exactly and every parenthesis is closed. Bar looks wrong? Temporarily show format(prop("% complete")) to confirm it's 0–1 vs 0–100.

✅ Project Completion Checklist

  • You added a progress bar formula driven by a rollup percentage
  • You added a status or 🔴🟡🟢 indicator formula
  • Each formula references your real property names (via prop())
  • Both appear on a Board or Gallery view where the visual is useful
  • Changing a row's data updates both formulas instantly

🎯 Quick Quiz

Question 1: What's the recommended way to use the recipes in this cookbook?

Question 2: The list functions map, filter, and find are introduced in this lesson as…

Best Practices for Formula Patterns

✅ Do's

  • Keep a personal formula stash — a Notion page of recipes you reuse.
  • Verify the raw value (with format()) when a recipe behaves oddly.
  • Favor the simplest recipe that works over a clever one you can't reread later.

❌ Don'ts

  • Don't treat the deep-dive as required. Lists and let() are bonuses.
  • Don't paste without swapping property names — that's the #1 cause of errors.
  • Don't build a monster formula when a rollup or button would do the job cleanly.

📓 Learning Journal

Keep a learning journal — for this course, the best place is inside your own Notion. After each lesson, take a few minutes to write down:

  • Key concepts you learned
  • Techniques that clicked for you
  • Questions or confusion points to revisit
  • Ideas you want to try
  • Your progress and feelings about learning this

✍️ This lesson's prompt: Which recipe do you think you'll reuse the most, and where will you keep your formula stash? Paste the two recipes you built into a "Formulas" note now — your future self, mid-build and impatient, will thank you.

📝 Lesson Summary

🎓 Key Takeaways

  • Formulas are a cookbook: copy a proven recipe, swap property names, verify — don't memorize.
  • Everyday recipes cover dates (days-until-due, next review), status (auto label, 🔴🟡🟢), and text (combine, trim).
  • A progress bar is just filled/empty squares sized from a rollup percentage.
  • format() turns numbers into text so you can join them to words.
  • The optional deep-dive — map/filter/find on lists and let() — adds power and readability, and is safe to skip.

🎉 What You've Accomplished

You now have real, working formulas in your workspace and a repeatable way to add more: copy, adapt, verify. That's the professional workflow — nobody writes these cold. Your system just got a lot more informative, and you didn't have to become a programmer to do it.

❓ Common Questions at This Stage

My progress bar shows the wrong length. What's off?

Almost always the percentage scale. Rollup percents usually come as 0–1 (0.3 = 30%); if yours is 0–100, divide by 100 first. Temporarily display format(prop("% complete")) to see the raw number, then adjust the recipe's multipliers.

Do I need the optional lists section to finish the project?

No. The project uses only the everyday recipes. map, filter, find, and let() are a clearly-marked bonus for when you're curious — your workspace won't miss them.

Can Notion AI just write formulas for me?

It can draft one from a plain-English description if you have the paid AI add-on. It's a great starting point — but still read and test what it produces. The skills here let you judge and fix its output rather than trust it blindly.

🔭 Looking Ahead

You've made databases smart. Next we make them reusable: Templates — Reuse Everything. You'll learn to save a page or database row as a template so you can spin up a new project, meeting note, or habit tracker in one click — with your formulas and structure already in place.

✅ Before the Next Lesson

  • Keep your progress bar and indicator formulas — templates will reuse this structure
  • Save your two recipes into a "Formulas" note for future copy-paste
  • Write your Learning Journal entry for this lesson

📚 Additional Resources

🌟 Encouragement for the Journey

You built a progress bar out of emoji and logic — and understood every piece. That's the difference between using Notion and commanding it. Keep your recipe stash close, copy without shame, and remember: the best formula is the simplest one that does the job. ⚗️