Here are general reasons why the error TypeError: “x.y is not a function” can occur in Angular or JavaScript, even if the function appears to be implemented:

1. Incorrect Context (this)

The method loses its binding to the original object, often due to how it’s passed or used (e.g. in a callback or event handler).

2. Object Is Not Initialized Properly

The object (x in x.y) is undefined or incorrectly assigned, so the method doesn’t exist on it at runtime.

3. Method Not Available on the Actual Object

Even though the method is implemented in a class, the instance being used is not of that class or is a plain object missing the method.

4. Typographical Error

There may be a typo in the method name when it’s being called, or a mismatch in casing.

5. Method Not Bound or Declared Properly

The function may be declared incorrectly — for example, as a standalone function instead of as a method within a class, so it’s not available on the object.

6. Asynchronous Timing Issue

The object or component is not fully initialized (e.g., data is not yet loaded), so the method isn’t present when accessed.

Here is the code which has issue

class:

export class Device {
 id: number; 
deviceID: string; 
name: string; 
location: string;
deviceType: string;
 subType: string; 
valueNamingMap: Object; 
addKeysToObj(deviceValues: object): void {
    for (let key of Object.keys(deviceValues).map((key) => { return key })) {
         if (!this.valueNamingMap.hasOwnProperty(key)) {
              this.valueNamingMap[key] = '';
       }
          console.log(this, deviceValues);
     }
}

And that is the call:

export class BatterieSensorComponent implements OnInit { 
@Input() device: Device; 
public result: Page = new Page(); //[..] 
ngOnInit() { 
   this.valueService.list('', this.device).subscribe( res => { 
   console.log(this.device); // NEW edit 1 
   This.result = res; if (this.result.count > 0) {            this.device.addKeysToObj(this.result.results[0]); 
} } ) 
} 
}

Solution :

Add this method to ensure any object passed in becomes a full Device instance with methods:

export class Device {
  id: number;
  deviceID: string;
  name: string;
  location: string;
  deviceType: string;
  subType: string;
  valueNamingMap: Object = {};
  addKeysToObj(deviceValues: object): void {
    for (let key of Object.keys(deviceValues)) {
      if (!this.valueNamingMap.hasOwnProperty(key)) {
        this.valueNamingMap[key] = '';
      }
    }
    console.log(this, deviceValues);
  }
  static fromPlain(obj: Partial): Device {
    return Object.assign(new Device(), obj);
  }
}

Use Device.fromPlain() before calling any methods on the device input.

export class BatterieSensorComponent implements OnInit {
  @Input() device: Device;
  public result: Page = new Page();
  ngOnInit() {
    // Ensure the `device` is a true Device instance
    this.device = Device.fromPlain(this.device);
    this.valueService.list('', this.device).subscribe(res => {
      this.result = res;
      if (this.result.count > 0) {
        this.device.addKeysToObj(this.result.results[0]);
      }
    });
  }
}

Need Help With Angular Development?

Work with our skilled Angular developers to accelerate your project and boost its performance.

Hire Angular Developers

Support On Demand!

Related Q&A