{"record":{"id":"b997daad6d9675e6","repo":"angular/components","slug":"maps-event-target-that-uses-native-events-must-hav","errorCode":null,"errorMessage":"Maps event target that uses native events must have `addEventListener` and `removeEventListener` methods.","messagePattern":"Maps event target that uses native events must have `addEventListener` and `removeEventListener` methods\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/google-maps/map-event-manager.ts","lineNumber":72,"sourceCode":"      switchMap(target => {\n        const observable = new Observable<T>(observer => {\n          // If the target hasn't been initialized yet, cache the observer so it can be added later.\n          if (!target) {\n            this._pending.push({observable, observer});\n            return undefined;\n          }\n\n          let handle: ListenerHandle;\n          const listener = (event: T) => {\n            this._ngZone.run(() => observer.next(event));\n          };\n\n          if (type === 'native') {\n            if (\n              (typeof ngDevMode === 'undefined' || ngDevMode) &&\n              (!target.addEventListener || !target.removeEventListener)\n            ) {\n              throw new Error(\n                'Maps event target that uses native events must have `addEventListener` and `removeEventListener` methods.',\n              );\n            }\n\n            target.addEventListener!(name, listener);\n            handle = {remove: () => target.removeEventListener!(name, listener)};\n          } else {\n            handle = target.addListener(name, listener)!;\n          }\n\n          // If there's an error when initializing the Maps API (e.g. a wrong API key), it will\n          // return a dummy object that returns `undefined` from `addListener` (see #26514).\n          if (!handle) {\n            observer.complete();\n            return undefined;\n          }\n\n          this._listeners.push(handle);","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/angular/components/blob/0411926e7d8ae06b32236ec1048a888cfad5abf2/src/google-maps/map-event-manager.ts#L54-L90","documentation":"When a Google Maps component subscribes to 'native' DOM events, the event manager attaches listeners directly to the target element via addEventListener/removeEventListener. This error is thrown (only in dev mode) when the object passed as an event target is missing either of those two methods, meaning the listener could not be attached reliably.","triggerScenarios":"Passing a custom object (e.g. a Marker-like wrapper, a proxied element, or a plain object) to MapEventManager.getLazyEmitter or to event-observable helpers where the event type resolves to 'native' and the target lacks addEventListener or removeEventListener methods.","commonSituations":"Wrapping Google Maps objects in custom classes that forward only some methods; using mocks/stubs from tests as event targets; using an older/alternate Maps API object shape; forgetting to spread or delegate the native event methods.","solutions":["Pass the actual native object (e.g. marker advancedMarkerElement content element, or the map's underlying DOM element) that implements addEventListener/removeEventListener","Ensure your custom target implements both addEventListener(type, listener) and removeEventListener(type, listener), delegating to the underlying element","If the event should be handled via the Maps JS API event system instead, use the correct event type (not 'native')"],"exampleFix":"// before\nclass FakeTarget { }\nmanager.getLazyEmitter('click').subscribe(...) // throws: no addEventListener\n// after\nclass FakeTarget {\n  addEventListener(t: string, l: EventListener) { el.addEventListener(t, l); }\n  removeEventListener(t: string, l: EventListener) { el.removeEventListener(t, l); }\n}","handlingStrategy":"validation","validationCode":"if (typeof target.addEventListener !== 'function' || typeof target.removeEventListener !== 'function') {\n  throw new TypeError('Event target must implement addEventListener and removeEventListener');\n}","typeGuard":"function isNativeEventTarget(t: unknown): t is EventTargetLike {\n  return !!t && typeof (t as any).addEventListener === 'function' && typeof (t as any).removeEventListener === 'function';\n}\ninterface EventTargetLike { addEventListener(type: string, l: EventListener): void; removeEventListener(type: string, l: EventListener): void; }","tryCatchPattern":"try {\n  emitter = manager.getLazyEmitter('click');\n} catch (e) {\n  console.error('Invalid native event target:', e);\n  // fall back to a different target or skip subscription\n}","preventionTips":["Only pass real DOM elements or verified Google Maps objects as native event targets","Type targets as EventTarget / a minimal interface so TS rejects incomplete objects","Avoid naive proxies that don't forward event methods"],"tags":["angular","google-maps","dev-mode","event-handling","missing-method"],"backgroundTag":"missing-required-method","analyzedSha":"0411926e7d8ae06b32236ec1048a888cfad5abf2","analyzedAt":"2026-08-31T11:58:23.400Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}