Angular 6:错误 TypeError:“...不是一个函数” - 但它是

2024-04-02

我现在真的很困惑,因为我得到了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]);
          }
        }
      )
    }
}

Edit 1

Logging this.device请参阅上面代码中的注释:

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

Edit 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>

原答案

你说,这是 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));
    }
  )
}

进一步解释

让我们尝试一个打字稿示例,因为这种行为与 Angular 没有任何关系。我们将使用localStorage表示来自外部源的数据,但这与 HTTP 的工作方式相同。

interface SimpleValue {
    a: number;
    b: string;
}

function loadFromStorage<T>(): T {
    // Get from local storage.
    // Ignore the potential null value because we know this key will exist.
    const storedValue = localStorage.getItem('MyKey') as string;

    // Note how there is no validation in this function.
    // I can't validate that the loaded value is actually T
    // because I don't know what T is.
    return JSON.parse(storedValue);
}

const valueToSave: SimpleValue = { a: 1, b: 'b' };
localStorage.setItem('MyKey', JSON.stringify(valueToSave));

const loadedValue = loadFromStorage<SimpleValue>();

// It works!
console.log(loadedValue);

效果很好,太棒了。 Typescript 接口纯粹是一个编译时结构,与类不同,它在 JavaScript 中没有等效项 - 它只是一个开发人员提示。但这也意味着如果您为外部值创建一个接口,例如SimpleValue上面,然后得到它wrong那么编译器仍然会相信你知道你在说什么,它不可能在编译时验证这一点。

从外部源加载类怎么样?有什么不同?如果我们以上面的例子为例并改变SimpleValue进入一个类而不改变任何其他东西那么它仍然有效。但有一个区别。与接口不同,类被转译为 JavaScript 等价物,换句话说,它们在编译之后就存在了。在上面的示例中,这不会导致问题,所以让我们尝试一个确实会导致问题的示例。

class SimpleClass {
    constructor(public a: number, public b: string) { }

    printA() {
        console.log(this.a);
    }
}

const valueToSave: SimpleClass = new SimpleClass(1, 'b');
localStorage.setItem('MyKey', JSON.stringify(valueToSave));

const loadedValue = loadFromStorage<SimpleClass>();

console.log(loadedValue.a); // 1
console.log(loadedValue.b); // 'b'
loadedValue.printA(); // TypeError: loadedValue.printA is not a function

加载的值具有我们期望的属性,但没有方法,呃哦!问题是方法是在以下情况创建的new SimpleClass叫做。当我们创建valueToSave我们确实实例化了该类,但随后我们将其转换为 JSON 字符串并将其发送到其他地方,而 JSON 没有方法的概念,因此信息丢失了。当我们加载数据时loadFromStorage we did not call new SimpleClass,我们只是相信调用者知道存储的类型是什么。

我们该如何处理这个问题?让我们暂时回到 Angular 并考虑一个常见的用例:日期。 JSON 没有日期类型,而 JavaScript 有,那么我们如何从服务器检索日期并使其像日期一样工作呢?这是我喜欢使用的模式。

interface UserContract {
    id: string;
    name: string;
    lastLogin: string; // ISO string representation of a Date.
}

class UserModel {
    id: string; // Same as above
    name: string; // Same as above
    lastLogin: Date; // Different!

    constructor(contract: UserContract) {
        // This is the explicit version of the constructor.
        this.id = contract.id;
        this.name = contract.name;
        this.lastLogin = new Date(contract.lastLogin);

        // If you want to avoid the boilerplate (and safety) of the explicit constructor
        // an alternative is to use Object.assign:
        // Object.assign(this, contract, { lastLogin: new Date(contract.lastLogin) });
    }

    printFriendlyLastLogin() {
        console.log(this.lastLogin.toLocaleString());
    }
}

import { HttpClient } from '@angular/common/http';
import { Injectable, Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Injectable({
    providedIn: 'root'
})
class MyService {
    constructor(private httpClient: HttpClient) { }

    getUser(): Observable<UserModel> {
        // Contract represents the data being returned from the external data source.
        return this.httpClient.get<UserContract>('my.totally.not.real.api.com')
            .pipe(
              map(contract => new UserModel(contract))
            );
    }
}

@Component({
    // bla bla
})
class MyComponent implements OnInit {
    constructor(private myService: MyService) { }

    ngOnInit() {
        this.myService.getUser().subscribe(x => {
            x.printFriendlyLastLogin(); // this works
            console.log(x.lastLogin.getFullYear()); // this works too
        });
    }
}

也许有点冗长,但这是我用来处理来自扁平后端合约的丰富前端模型的最强大和最灵活的模式。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Angular 6:错误 TypeError:“...不是一个函数” - 但它是 的相关文章

  • 如何在 Sequelize ORM 中限制连接行(多对多关联)?

    Sequelize 定义了两种模型 具有多对多关联的 Post 和 Tag Post belongsToMany db Tag through post tag foreignKey post id timestamps false Tag
  • Javascript 在另一个函数中检测“Shift”键按下

    我正在从 Flash 影片 使用外部接口 调用我的 html 页面中的 Javascript 函数 并且我想知道调用该函数时用户是否按下了 Shift 键 例如 如果我通过鼠标单击调用该函数 这似乎很简单 因为我可以传递事件并检查 if e
  • NestJS e2e 测试模拟会话装饰器

    我正在尝试使用 supertest 编写一个 e2e 测试 其中我的控制器实际上使用了 Session 装饰师 然而 我不想承担使用数据库连接等启动会话的全部负担 因此测试中的我的应用程序实际上并未初始化会话 相反 我想首先模拟掉装饰器提供
  • 在动态创建的元素上添加事件监听器[重复]

    这个问题在这里已经有答案了 是否可以向所有动态生成的元素添加事件侦听器 Javascript 我不是页面的所有者 因此我无法以静态方式添加侦听器 对于页面加载时创建的所有元素 我使用 doc body addEventListener cl
  • html canvas动画卡顿

    谁能解释为什么提供的画布动画断断续续 我创建了一个测试存根来演示该问题 我在桌面上的 FF Chrome IE 以及 Android 上的 FF 和 Chrome 中看到了卡顿现象 口吃是由于垃圾收集造成的吗 似乎 raf 在每次调用时都会
  • 为什么我们使用 SpreadsheetApp.flush()?

    我的理解是 flush https developers google com apps script reference spreadsheet spreadsheet app flush有助于在功能发生时执行这些功能 而无需将它们捆绑在
  • 如何知道浏览器空闲时间?

    如何跟踪浏览器空闲时间 我用的是IE8 我没有使用任何会话管理 也不想在服务器端处理它 这是纯 JavaScript 方法来跟踪空闲时间 并在达到一定限制时执行一些操作 var IDLE TIMEOUT 60 seconds var idl
  • put方法中的Angularjs文件上传不起作用

    我有一个简单的待办事项应用程序 我试图在其中上传照片和单个待办事项 现在我已经创建了这个工厂函数来负责待办事项的创建 todosFactory insertTodo function todo return http post baseUr
  • 尝试使用 Firebug 查找 JavaScript 文件中的函数

    我试图找到这个函数调用 myFooBar 该函数在某些 HTML 中内联引用 但页面加载了大量 JavaScript 并且在每个文件中搜索该函数需要相当多的工作 如何使用 Firebug 找到此函数所在的 JavaScript 文件 打开脚
  • 如何让 vsCode 了解自动补全的深度依赖导入?

    我创建了多个角度库 让我可以使用一堆组件更快地创建网站 例如 sidenav 卡片 我创建了一个 超级库 来导入所有这些库 这样我就可以使用npm i myWebsiteBundle立即下载所有依赖项 我已将每个类似的插件列入白名单ng p
  • jQuery 悬停时滚动到 div 并返回到第一个元素

    我基本上有一个具有设定尺寸的 div 和overflow hidden 该 div 包含 7 个子 div 但一次只显示一个 我希望当它们各自的链接悬停时能够平滑地垂直滚动 但是 第一部分 div 没有链接 并且是没有悬停链接时的默认部分
  • 根据特定字符获取整个字符串或子字符串

    我有一个包含 MIME 类型的字符串 例如application json 现在我想将其与实际的 HTTP 标头进行比较 在本例中content type 如果标头包含 MIME 类型 那么就很简单 if mimeType contentT
  • JavaScript 中的实时摩尔斯电码转换器

    在看到谷歌关于莫尔斯电码 gmail 的愚人节笑话后 我想我应该尝试用 javascript 创建一个实时莫尔斯电码转换器 我正在使用正则表达式和替换将莫尔斯电码更改为字符 例如 replace g a replace g r 我遇到的问题
  • Outlook 加载项,无法读取未定义的属性“BeginRequestEventArgs”

    我使用 Visual Studio 开发了 Outlook 插件 我的插件有一个按钮 用于填充会议邀请正文中的详细信息并添加所需的与会者 这在 99 的情况下都有效 但是 时不时地它会给我下面的 JavaScript 错误 Uncaught
  • Dart 中的字符串文字类型(如 TypeScript)?

    感谢 Flutter 我开始使用 Dart 而且我非常喜欢这门语言 我之前使用过 TypeScript 它提供了一些我以前从未见过的非常酷的功能 我特别喜欢的是字符串文字类型 https www typescriptlang org doc
  • 检测浏览器选项卡是否具有焦点

    是否有可靠的跨浏览器方法来检测选项卡是否具有焦点 场景是 我们有一个定期轮询股票价格的应用程序 如果页面没有焦点 我们可以停止轮询并为每个人节省流量噪音 特别是当人们喜欢打开具有不同投资组合的多个选项卡时 Is window onblur
  • 具有固定顶部菜单的语义 UI 侧边栏

    Semantic UI 对其进行预警侧边栏页面 http semantic ui com modules sidebar html usage 当侧边栏出现时 固定位置内容可能会出现改变其位置的问题 然后它提供了该问题的两种可能的解决方案
  • Angular 7测试重试当模拟http请求无法实际重试时

    我有以下尝试使用 OAuth 的拦截器refresh token每当获得任何 401 错误 响应时 基本上 刷新令牌是在第一个 401 请求上获取的 获取后 代码会等待 2 5 秒 在大多数情况下 第二个请求不会触发错误 但如果触发错误 令
  • p5 向量减法“sub”返回错误

    我一直在尝试将 p5 草图上传到 React 构建中 使用react p5 wrapper 我能够成功在屏幕上渲染画布 但是 某些矢量函数会导致错误 var distance this position dist ball position
  • 如何获得 JavaScript 阶乘程序的循环来显示所使用的工作?

    你好 我面临着用 JavaScript 编写一个程序的挑战 尽管我对它不太了解 但它要求用户输入一个数字 然后计算该数字的阶乘 我使用了已经提出的问题并设法使计算正常工作 但无法获得所需的输出 我必须在以下输出中获取它 而不使用任何花哨的库

随机推荐

  • GC 会从元空间收集垃圾吗?

    我一直认为垃圾收集器只清除堆 现在我也这么认为 在java 8中permGen被删除并被Metaspace取代 据我了解元空间是垃圾收集的 https stackoverflow com a 24075360 2674303 https s
  • 在Python交互窗口VSCode中交换shift-enter和回车

    In the interactive window in vscode you press shift enter to run the code you just typed and enter to go to the next lin
  • 为什么compareTo返回一个整数

    我最近在一个 SO 聊天中看到了一个讨论 但没有明确的结论 所以我最终在那里询问 这是出于历史原因还是与其他语言的一致性 在查看签名时compareTo各种语言 它返回一个int 为什么它不返回枚举 例如 在 C 中我们可以这样做 enum
  • 创建对象的数组列表

    如何用对象填充 ArrayList 并且其中的每个对象都不同 ArrayList
  • Kafka 0.8,是否可以使用java代码创建带有分区和复制的主题?

    在 Kafka 0 8beta 中 可以使用下面提到的命令创建主题here http kafka apache org 08 quickstart html bin kafka create topic sh zookeeper local
  • 如何每隔 n 个字符或最近的前一个空格分割字符串

    我想每 15 个字符 包括空格 插入一个换行符 我目前正在使用下面的正则表达式 它在某种程度上起作用 但它占用了单词后最近的空格 并且我想要最近的前一个空格 有任何想法吗 const split str replace s S 15 g 1
  • 拆分 ng 重复项?

    简单的问题 如果我的控制器中有这个 scope somedata Item 1 Item 2 set from something else 有没有办法在 ngRepeat 表达式中分割我的视图的一些数据 就像是 div item div
  • ApiController Post 中的 Async 和 Await

    我仍然不太清楚 net 4 5 中的 async 和 wait 到目前为止 我想我明白了等待 将函数 在其右侧 放在单独的线程上 将执行返回给当前函数的调用者 但会 劫持 当前函数代码的其余部分 直到等待 异步 函数完成 如果我误解了什么
  • 当前上下文中不存在名称“...”

    我的里面有一个清单Main 我正在尝试从变量中将一个项目添加到该列表中 但它抛出了错误 名称 dogList 在当前上下文中不存在 在我的里面addDog 方法 dogList Add 由于上述原因无法正常工作 namespace Dogg
  • postgresql 的 mysql_insert_id 替代品

    有没有替代方案mysql insert id PostgreSQL 的 php 函数 大多数框架通过查找 ID 中使用的序列的当前值来部分解决问题 但是 有时主键不是串行列 从 PostgreSQL 的角度来看 用伪代码来说 insert
  • Android 中的上传和下载速率分析[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我正在尝试开发一个 Android 应用程序来测量网络的上传和下载速度 我可能需要每 2 秒左右运行一次并对其进行分析 SpeedTe
  • return Json 函数没有更新我的下拉列表

    我有一个包含填充下拉列表的视图 我添加了一个按钮 以便用户可以在 jquery 模式中添加新的下拉列表值 因此当用户单击添加新的下拉列表值时 我想刷新下拉列表 但目前没有任何更新 这是我对下拉列表的看法 model Communique M
  • 调用方法出错,启动jvm失败

    我正在使用 javafx v8 0 40 开发桌面应用程序 我用inno 5创建了一个exe文件 当我在计算机中运行exe文件时 它已安装并运行 没有任何问题 另一方面 当我尝试在其他计算机上安装并运行它时 在安装结束时 会弹出窗口对话框
  • 创建文件系统“驱动程序”

    我想为 Windows 物理磁盘上的自定义文件系统创建一个 驱动程序 我不完全知道解释它的最佳方式 但该设备已经具有适当的驱动程序以及 Windows 与之通信的所有内容 但我希望用户能够将设备插入到他们的电脑 将其显示在 我的电脑 中 并
  • 调用 didEnterBackground 后是否可以在主线程上执行某些操作?

    首先 如果您认为我的问题是虚拟的 我想说声抱歉 我是 iOS 和多线程的新手 只是想了解事情是如何发生的 据我所知didEnterBackground是 iOS 在应用程序挂起之前调用的最后一个函数 应用程序有大约 5 秒的时间从中返回 否
  • 用不均匀向量列表中的正值替换正表值

    背景 我最近问这个问题 https stackoverflow com questions 72899527 replacing a subset of table values with a list of vectors 然而 我使示例
  • 在 Excel 中打开特定电子表格的 win cmd 是什么?

    我知道您可以从 win cmd 行打开 Excel 文件 但是如何使用 win cmd 打开该文件中的特定电子表格呢 将以下代码粘贴到文本编辑器 记事本 写字板 Word ETC 例如 使用 vbs 扩展名保存文件 ExcelSheet2
  • 使用 Javascript 将数据/有效负载发送到 Google Chrome 推送通知

    我正在研究 Google Chrome 推送通知 并尝试将有效负载发送给 google Chrome 工作人员 但是我不知道如何接收此有效负载 我有一个 API 可以在数据库中创建和保存通知 我需要通过以下方式发送值 https andro
  • JACC 提供程序如何使用其部署的服务器的主体到角色映射功能?

    我正在写一个JACC提供者 在此过程中 这意味着实施PolicyConfiguration http download oracle com javaee 6 api javax security jacc PolicyConfigurat
  • Angular 6:错误 TypeError:“...不是一个函数” - 但它是

    我现在真的很困惑 因为我得到了ERROR TypeError this device addKeysToObj is not a function 但我实现了这个函数 所以我不知道有什么问题或者为什么它不可调用 我已经在 Firefox 和