角度6:错误TypeError:“ ...不是函数”-而是

时间:2018-08-09 09:44:29

标签: javascript angular typescript

我现在真的很困惑,因为我得到了ERROR TypeError: "_this.device.addKeysToObj is not a function"。但是我实现了该功能,所以我不知道是什么问题或为什么它不能被调用。我已经尝试过使用Firefox和chrome的代码,都遇到了相同的错误。

错误在第this.device.addKeysToObj(this.result.results[0]);

这是我的课程:

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);
    }
}

那就是电话:

export class BatterieSensorComponent implements OnInit {
    @Input() device: Device;
    public result: Page<Value> = new Page<Value>();

    //[..]

    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]);
          }
        }
      )
    }
}

编辑1

登录this.device,请参见上面的代码中的注释:

{
    deviceID: "000000001" 
    deviceType: "sensor"    ​
    id: 5    ​
    location: "-"
​    name: "Batteries"    ​
    subType: "sensor"    ​
    valueNamingMap:
      Object { v0: "vehicle battery", v1: "Living area battery" }
    <prototype>: Object { … } 
}

编辑2

device.service代码的一部分:

list(url?: string, deviceType?: string, subType?: string): Observable<Page<Device>> {
  if(!url) url = `${this.url}/devices/`;
  if(deviceType) url+= '?deviceType=' + deviceType;
  if(subType) url+= '&subType=' + subType;

  return this.httpClient.get<Page<Device>>(url, { headers: this.headers })
    .pipe(
      catchError(this.handleError('LIST devices', new Page<Device>()))
    );
}

父组件中的调用

ngOnInit() {
  this.deviceService.list('', 'sensor', ).subscribe(
    res => { 
      this.devices = res.results;
    }
  )
}

模板:

<div class="mdl-grid">
  <div class="mdl-cell mdl-cell--6-col mdl-cell--6-col-tablet" *ngFor="let device of devices">
    <app-batterie-sensor [device]="device"></app-batterie-sensor>
  </div>
</div>

3 个答案:

答案 0 :(得分:18)

这是Typescript的常见陷阱,您说device的类型为Device,但实际上不是。它具有与Device相同的所有属性,但是由于它实际上不是Device,因此没有预期的方法。

您需要确保为Device中的每个条目(可能在父组件的Page中)实例化ngOnInit

我不知道Page的结构,但是如果它是数组,请尝试以下操作。

ngOnInit() {
  this.deviceService.list('', 'sensor', ).subscribe(
    res => { 
      this.devices = res.results.map(x => Object.assign(new Device(), x));
    }
  )
}

答案 1 :(得分:0)

就我而言,我测试了两种对我有用的解决方案

将代码包装在 setTimeout

ngOnInit() {
  setTimeOut({ // START OF SETTIMEOUT
    this.deviceService.list('', 'sensor', ).subscribe(
      res => { 
        this.devices = res.results.map(x => Object.assign(new Device(), x));
      }
    )
  }); // END OF SETTIMEOUT
}

其他解决方案是添加一个条件

ngOnInit() {
  if(typeof this.deviceService.list === 'function'){ // START OF CONDITION
    this.deviceService.list('', 'sensor', ).subscribe(
      res => { 
        this.devices = res.results.map(x => Object.assign(new Device(), x));
      }
    )
  } // END OF CONDITION
}

答案 2 :(得分:0)

您可能遇到了与接受的答案不同的问题:如果您使用的是 Angular 的服务而忘记了 @Injectable,使用 Angular Ivy,您会遇到如下运行时异常:

ERROR TypeError: ConfigurationServiceImpl.\u0275fac is not a function

正确的解决方案是将 @Injectable 也加入到实现中,例如:

// do not omit the @Injectable(), or you'll end up with the error message!
@Injectable()
export class ConfigurationServiceImpl implements ConfigurationService {
...
}

@Injectable({
  providedIn: "root",
  useClass: ConfigurationServiceImpl,
})
export abstract class ConfigurationService {
...
}

另见Angular 7 TypeError: service.x is not a function