Hello Devs,
You know that moment when everything looks fine — no errors, no warnings — but the UI just... doesn’t do what it’s supposed to?
That’s how this story begins.
But let me add some background first...
🧳 Returning to Angular After 5 Years
I recently jumped back into Angular after almost five years away.
Things I used to know by heart?
Gone or evolved.
There’s standalone: true
now. Modules are optional. Components feel more like islands.
It’s Angular — but... different.
So when I decided to build a simple standalone navbar component with a dropdown filter, I felt ready to dive in.
After all, how hard could *ngFor
be?
Turns out, harder than I expected — if you're doing it blindly.
🚧 The Setup
I was building a home-navbar
component — a simple filter with values like “Latest”, “Trending”, and “Following”.
In home-navbar.component.ts
, I had:
filterOptions = ['latest', 'trending', 'following'];
And in the template:
*ngFor="let option of filterOptions">{{ option }}
So clean. So elegant.
So... not working.
😵💫 Debugging the Invisible
No errors. No warnings. Just an empty
.
The kind of bug where Angular doesn’t even bother complaining — it just shrugs.
Here’s what I tried:
✅
console.log(filterOptions)
— the array was there.✅
{{ filterOptions }}
in the template — rendered just fine.❌
*ngFor
— ignored. Like it didn’t exist.
I even replaced it with:
*ngFor="let item of ['a', 'b', 'c']">{{ item }}
Still nothing.
Then I tried this:
*ngIf="true">Hello ngIf
And when that didn’t render...
Something snapped.
💡 The Realization
After spiralling a bit, I checked the docs. Then it hit me:
This is a standalone component. It doesn’t inherit anything — not even Angular’s own core directives.
And that’s when I realised what I had missed all along:
import { CommonModule } from '@angular/common';
@Component({
standalone: true,
...
imports: [CommonModule, ...] // ← The missing piece
})
That one tiny line. That was the reason everything was failing — silently.
🔍 Why It Happens
In Angular:
If you're using regular components inside an
NgModule
, importingCommonModule
once covers all declared components.But if you're building standalone components, they’re completely self-contained.
That means you must import
CommonModule
yourself, or you won’t get*ngIf
,*ngFor
,| date
,| currency
, etc.
🤦 Lesson from the Drama
I was so focused on building the UI and making things work that I forgot to stop and ask:
"Wait, where do structural directives even come from?"
This was a great reminder:
Even as someone experienced, it's easy to fall into habits — and overlook small things that matter.
The truth is, I wasn't "doing Angular" — I was doing muscle memory.
And Angular? It has changed.
✅ The Fix
This one line saved my sanity:
imports: [CommonModule]
Once I added that, *ngFor
worked. *ngIf
worked. Everything came back to life.
✨ Update: Angular 17+ Way Without CommonModule
Starting from Angular 17, there's an even cleaner way to handle loops without needing to import CommonModule
at all!
✅ You can now use the new @for
and @if
syntax directly in your templates.
Example:
<ul>
@for (option of filterOptions; track $index) {
<li>{{ option }}</li>
}
</ul>
or conditionally:
@if (filterOptions.length > 0) {
<p>We have {{ filterOptions.length }} options!</p>
}
🏆 Best Practice
For Angular 16 and below:
UseCommonModule
.For Angular 17 and above:
Prefer@for
and@if
syntax.If you need to support older versions, stick to the
*ngFor
and*ngIf
approach with CommonModule.
🔑 Takeaways
Standalone components mean standalone responsibilities.
Nothing is auto-included — you explicitly manage what your component needs.No CommonModule?
Then no*ngFor
, no*ngIf
, no pipes — and no warnings either.
Angular will silently skip them, leaving you scratching your head.Coming back to a framework after years?
Don't assume things work like they used to.
Even familiar tools evolve — often in small, silent ways.Tiny details break things quietly.
Always slow down and verify the basics — they are the first place things go wrong.Bonus for Angular 17+:
The new@for
and@if
syntax means even less boilerplate — no CommonModule needed at all!
🗯️ Have You Had “Silent Failures” Too?
Ever spent hours debugging only to realise one import was missing?
Or a component didn’t behave because of a silent Angular rule?
Share your moment.
Let’s normalise the messy middle part of learning and relearning.
Because sometimes, it’s not about knowing Angular.
It’s about knowing what to double check.