{"record":{"id":"2732c1fd04da3236","repo":"TanStack/table","slug":"tanstack-angular-table-cannot-initialize-object","errorCode":null,"errorMessage":"[@tanstack/angular-table] Cannot initialize object after view is destroyed","messagePattern":"\\[@tanstack/angular-table\\] Cannot initialize object after view is destroyed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/angular-table/src/injectLazyInit.ts","lineNumber":26,"sourceCode":"const notInitializedObject = Symbol('notInitializedObject')\n\nexport function injectLazyInit<T extends object>(\n  initializer: () => T,\n  cleanup: (object: T) => void,\n): T {\n  assertInInjectionContext(injectLazyInit)\n  const destroyRef = injectCompatibleDestroyRef()\n  let object: T | typeof notInitializedObject = notInitializedObject\n\n  destroyRef.onDestroy(() => {\n    if (object !== notInitializedObject) {\n      cleanup(object)\n    }\n  })\n\n  const getObject = () => {\n    if (destroyRef.destroyed && object === notInitializedObject) {\n      throw new Error(\n        '[@tanstack/angular-table] Cannot initialize object after view is destroyed',\n      )\n    }\n    if (object === notInitializedObject) {\n      object = untracked(initializer)\n    }\n    return object\n  }\n\n  return new Proxy<T>({} as T, {\n    get(_, prop, receiver) {\n      return Reflect.get(getObject(), prop, receiver)\n    },\n    has(_, prop) {\n      return Reflect.has(getObject(), prop)\n    },\n    ownKeys() {\n      return Reflect.ownKeys(getObject())","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/TanStack/table/blob/d01c01bedbab0ff6c2641f18b2fc9a11545d9bf6/packages/angular-table/src/injectLazyInit.ts#L8-L44","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nngOnDestroy() {\n  this.table.rowSelection = {}; // first touch after destroy -> throws\n}\n// after\nngOnInit() {\n  this.table = this.lazyTable; // force init while alive\n}\nngOnDestroy() {\n  if (this.destroyRef.destroyed) return;\n  this.table.rowSelection = {};\n}","handlingStrategy":"type-guard","validationCode":"if (!this.destroyRef.destroyed) {\n  this.table = this.lazyTable; // force init while alive\n}","typeGuard":"function canAccessLazy(destroyRef: DestroyRef, initialized: boolean): boolean {\n  return initialized || !destroyRef.destroyed;\n}","tryCatchPattern":"try {\n  doSomethingWith(lazyTableProxy);\n} catch (e) {\n  if (e.message.includes('after view is destroyed')) {\n    // view already destroyed; skip\n  } else { throw e; }\n}","preventionTips":["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"],"tags":["angular","lifecycle","destroyed-view","lazy-init"],"backgroundTag":"access-after-destroy","analyzedSha":"d01c01bedbab0ff6c2641f18b2fc9a11545d9bf6","analyzedAt":"2026-08-28T21:52:44.679Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}