【问题标题】:Cannot read property 'emit' of undefined when trying to emit a document尝试发出文档时无法读取未定义的属性“发出”
【发布时间】:2020-08-04 00:32:27
【问题描述】:

我正在尝试使用ReactJSPouchDB 中的实体标签创建design。我设法使用put 函数保存了我的设计,但是当我查询我的设计时,响应只是一个空数组,我在控制台中收到以下错误:

TypeError: Cannot read property 'emit' of undefined

我认为问题出在我后来用作设计变量的映射参数的函数中:

function emitTagsMap(doc)
{
  if (doc !== undefined)
  {
    if (Array.isArray(doc.tags))
    {
       doc.tags.forEach(x =>
       {
          /* Here is probably the problem - this.db is undefined */
          this.db.emit(x, null);
       });
     }
   }
};

this.db 在构造函数中声明:

constructor(service, name)
{
        if (!service || !name) throw new Error("PouchDatabase initialized incorrectly");
        this.name = name;
        this.db = new PouchDB(name);
        this.service = service;
        this.tagsView();
}

请记住,我对PouchDB 完全陌生。

任何想法如何初始化emit 函数?

提前谢谢你。

【问题讨论】:

  • 您能否发布您的 emitTagsMap 函数周围的代码。 this.db 在哪里声明?
  • 我在代码中添加了构造函数,这就是声明this.db的地方
  • 尝试以这种方式编写您的方法 emitTagsMap = (doc) => {....}

标签: reactjs pouchdb


【解决方案1】:

您不需要通过数据库对象调用 emit。

试试这个:

function emitTagsMap(doc)
{
  if (doc !== undefined)
  {
    if (Array.isArray(doc.tags))
    {
       doc.tags.forEach(x =>
       {
          emit(x, null);
       });
     }
   }
};

根据 PouchDB 文档,设计文档是这样形成的:

// first create a new design doc and pass your map function as string into it
var ddoc = {
      _id: "_design/my_index",
      views: {
        by_name: {
         map: "function (doc) {         if (doc !== undefined) {          if (Array.isArray(doc.tags)) {            doc.tags.forEach(x => {              emit(x, null);            });          }        }      }"
        }
      }
    };

// save it
db.put(ddoc).then(function () {
  // success!
}).catch(function (err) {
  // some error (maybe a 409, because it already exists?)
});

//Then you actually query it, by using the name you gave the design document when you saved it:

db.query('my_index/by_name').then(function (res) {
  // got the query results
}).catch(function (err) {
  // some error
});

https://pouchdb.com/guides/queries.html

【讨论】:

  • 我想将我的函数用作设计的映射参数。
  • 请查看下方代码示例。您的发射标签映射现在是设计文档 my_index 的一部分。如果您复制整个块,它应该可以工作。您可能需要将 db.query 和 db.put 更改为您的数据库。
  • 这会使应用程序崩溃 - 'emit' 未定义。这就是为什么我一直使用 this.db.emit 而 this.db 是 PouchDB 的实例
  • @AdamSulc 我更新了我的答案,如果地图函数保存为字符串,请检查它是否有效。
  • 现在可以使用了。它真的很奇怪,我的意思是如果有 .toString() 会期望它会做同样的事情只是把它放在一个大字符串中。谢谢
【解决方案2】:

我假设你的函数是 JavaScript 类的一部分(否则你必须用this 解释这个想法)。在 ES6 中,您必须将 this 绑定到您的常规函数​​。你有两个选择:

首先 - 通过构造函数绑定它:

constructor() {
  this.emitTagsMap = this.emitTagsMap.bind(this);
}

第二 - 将函数声明为箭头。这样,react 就会为你绑定它:

emitTagsMap = (doc) =>
{
  if (doc !== undefined)
  {
    if (Array.isArray(doc.tags))
    {
       doc.tags.forEach(x =>
       {
          /* Here is probably the problem - this.db is undefined */
          this.db.emit(x, null);
       });
     }
   }
};

【讨论】:

  • 我试图将函数声明为箭头函数,但编译器没有它('('预期。)。可能是因为我在方法中定义了函数吗?
  • 由于是类的一部分,所以不需要使用关键字function,而是将其声明为常规变量。我更新了答案,请看一下。
  • 我应该将它定义为一个常量吗?它的行为真的很奇怪,如果我的代码与您的答案相同,那么我不能将 emitTagsMap 函数作为我设计的地图参数(未定义)。
  • 不,你必须在你的类内部定义它。然后调用它,使用this.emitTagsMap(doc)
  • 不幸的是,由于某种原因,控制台仍然返回相同的错误。我真的不明白为什么,因为你的解决方案对我来说很有意义。
猜你喜欢
  • 2017-06-20
  • 2019-08-21
  • 1970-01-01
  • 1970-01-01
  • 2021-01-29
  • 2021-07-09
  • 1970-01-01
  • 1970-01-01
  • 2021-10-23
相关资源
最近更新 更多