This content originally appeared on DEV Community and was authored by Rajat
Article: Are You Misusing Signals in Angular? Here Are 5 Mistakes You Might Be Making
Have you recently started using Signals in Angular and felt something was off?
With Angular’s reactivity model getting a big boost thanks to Signals, many developers are rushing to adopt them—but in the process, they’re making subtle (and costly) mistakes that hurt performance, readability, or the reactive flow itself.
In this article, we’ll walk through 5 common mistakes developers make when using Angular Signals—and more importantly, how to fix them with clean, professional code. Each mistake includes interactive, copy-ready demo code so you can try it right away.
What Will You Learn by the End?
- How Angular Signals work under the hood
- The right way to subscribe, mutate, and combine signals
- How to optimize performance and avoid unnecessary re-renders
- Best practices that scale in production
- Confidence using Signals in your Angular 17+ apps
Mistake #1: Using Signals Like Observables
Many developers coming from RxJS assume signals behave like observables—but they don’t.
Wrong Way:
const count = signal(0);
count.subscribe(val => {
console.log(val); // ❌ subscribe doesn't exist!
});
Right Way:
const count = signal(0);
effect(() => {
console.log('Current count:', count());
});
Why It Matters:
Signals are pull-based, not push-based. You access their value via a getter call count()
and respond to changes with effect()
.
Mistake #2: Mutating Signal State Incorrectly
Avoid directly modifying the state of a signal like a regular variable.
Wrong Way:
const user = signal({ name: 'John' });
user().name = 'Jane'; // ❌ won't trigger reactivity
Right Way:
user.update(prev => ({ ...prev, name: 'Jane' }));
Tip: Always use
set()
, update()
, or mutate()
for changing signal values. Direct mutations are ignored by Angular’s reactivity system.
Mistake #3: Ignoring computed()
When Needed
You’re manually calculating values every time instead of using computed.
Wrong Way:
const first = signal('John');
const last = signal('Doe');
const fullName = `${first()} ${last()}`; // Recomputed manually
Right Way:
const fullName = computed(() => `${first()} ${last()}`);
Demo Component:
@Component({
selector: 'app-name',
standalone: true,
template: `
<p>Full Name: {{ fullName() }}</p>
<button (click)="updateName()">Change Name</button>
`,
})
export class NameComponent {
first = signal('John');
last = signal('Doe');
fullName = computed(() => `${this.first()} ${this.last()}`);
updateName() {
this.first.set('Jane');
this.last.set('Smith');
}
}
Mistake #4: Nesting Signals Deeply Inside Objects
Signals inside objects can lead to hard-to-track updates and inefficient change detection.
Anti-pattern:
const profile = signal({
name: signal('John'),
age: signal(30)
});
Better:
const name = signal('John');
const age = signal(30);
Pro Tip: Prefer flat signals over deeply nested structures. It simplifies effects and debugging.
Mistake #5: Forgetting to Clean Up effect()
effect() lives as long as the component does. But in services or dynamic lifecycles, cleanup is important.
Risky:
effect(() => {
console.log('Tracking...');
});
Safe (using
runInInjectionContext
):
@Injectable()
export class MyService {
constructor(@Inject(EffectCleanup) cleanup: () => void) {
const stop = effect(() => {
// effect logic
});
cleanup(() => stop()); // Clean it when the service is destroyed
}
}
Best Practice: When outside a component (e.g., in services), ensure
effect()
is cleaned up to avoid memory leaks.
Wrapping Up
Angular Signals offer a leaner, cleaner, and faster reactivity model—but only if used correctly.
Key Takeaways:
- Don’t treat signals like RxJS
- Use
computed()
to encapsulate derived values - Use
effect()
for side effects—not just logging - Never mutate signal state directly
- Avoid deeply nested signal structures
Let’s Talk!
Which of these mistakes have you made?
Got any other pitfalls or smart tips around Signals in Angular?
Your Turn!
Was this article helpful for you?
Are you already using it in your project?
Drop your experience or questions in the comment section below—I’d love to discuss them with you.
I would love to hear how you are using it or if you have any doubts I can clear.
If you found this helpful, please share this article with your dev circles!
Follow me for more Angular deep-dives, code tips, and modern frontend strategies:
Cheers to cleaner, better code!!!
And, if you found this article helpful, a clap **and a **follow would be much appreciated
Stay tuned for more Angular tips, tricks, and real-world guides!
This content originally appeared on DEV Community and was authored by Rajat