TanStack/table · error
[@tanstack/angular-table] Cannot initialize object after vie
Error message
[@tanstack/angular-table] Cannot initialize object after view is destroyed
What it means
injectLazyInit creates a lazily initialized object tied to an Injector and DestroyRef. If the object was never initialized (still notInitializedObject) and the view is already destroyed, lazy initialization is impossible, so getObject throws this error instead of silently creating a leaked object.
Source
Thrown at packages/angular-table/src/injectLazyInit.ts:26
const notInitializedObject = Symbol('notInitializedObject')
export function injectLazyInit<T extends object>(
initializer: () => T,
cleanup: (object: T) => void,
): T {
assertInInjectionContext(injectLazyInit)
const destroyRef = injectCompatibleDestroyRef()
let object: T | typeof notInitializedObject = notInitializedObject
destroyRef.onDestroy(() => {
if (object !== notInitializedObject) {
cleanup(object)
}
})
const getObject = () => {
if (destroyRef.destroyed && object === notInitializedObject) {
throw new Error(
'[@tanstack/angular-table] Cannot initialize object after view is destroyed',
)
}
if (object === notInitializedObject) {
object = untracked(initializer)
}
return object
}
return new Proxy<T>({} as T, {
get(_, prop, receiver) {
return Reflect.get(getObject(), prop, receiver)
},
has(_, prop) {
return Reflect.has(getObject(), prop)
},
ownKeys() {
return Reflect.ownKeys(getObject())View on GitHub (pinned to d01c01bedb)
Solutions
- Access/initialize the lazily created object while the view is alive (e.g. in the constructor, init, or an effect) so it exists before teardown
- Guard destroy-time reads with destroyRef.destroyed (or injector.get( DestroyRef).destroyed) before touching the object
- Unsubscribe from async callbacks on destroy so they never touch the object after the view is gone
Example fix
// before
ngOnDestroy() {
this.table.rowSelection = {}; // first touch after destroy -> throws
}
// after
ngOnInit() {
this.table = this.lazyTable; // force init while alive
}
ngOnDestroy() {
if (this.destroyRef.destroyed) return;
this.table.rowSelection = {};
} Defensive patterns
Strategy: type-guard
Validate before calling
if (!this.destroyRef.destroyed) {
this.table = this.lazyTable; // force init while alive
} Type guard
function canAccessLazy(destroyRef: DestroyRef, initialized: boolean): boolean {
return initialized || !destroyRef.destroyed;
} Try / catch
try {
doSomethingWith(lazyTableProxy);
} catch (e) {
if (e.message.includes('after view is destroyed')) {
// view already destroyed; skip
} else { throw e; }
} Prevention
- Touch lazy objects during component init so they are created before any teardown
- Guard ngOnDestroy/cleanup code with destroyRef.destroyed checks
- Unsubscribe from async work on destroy so callbacks never run after teardown
When it happens
Trigger: Accessing a lazily initialized object (via get/has/ownKeys on the lazy proxy) after its DestroyRef has been destroyed and before it was ever initialized — e.g. reading a table instance in onDestroy/after destruction or in a detached callback.
Common situations: Cleanup/destroy hooks that touch the table instance for the first time; async callbacks resolving after the component view was destroyed (HTTP subscriptions, setTimeout); effects running during teardown.
Related errors
AI-assisted analysis of TanStack/table@d01c01bedb (2026-08-28).
Data as JSON: /api/errors/2732c1fd04da3236.
Report an issue: GitHub.