javascript - 通过 $set 更改对象属性给出:“TypeError: Cannot read property 'call' of undefined”
问题描述
首先,你好。
我对 Web 开发和 Vue.js 或 Javascript 比较陌生。我正在尝试实现一个系统,使用户能够上传图片和视频并为其投票。一般来说,整个系统都工作。但是因为我从服务器获取了所有信息,所以用于显示文件的对象 + 它们的统计信息不是反应性的。我试图改变我将对象的属性从 "file['votes'] ) await data.data().votes" 更改为 "file.$set('votes', await data.data().votes )”。但是现在我得到了 TypeError: Cannot read property 'call' of undefined Error。我不知道为什么会发生这种情况,或者这个错误甚至意味着什么。在互联网上搜索了很多之后,我找不到任何有同样问题的人。我的方法一定有遗传上的错误。
如果有人能给我解释正在发生的事情或者能给我一个更好的方法来处理我的问题,我将非常感激。
提前感谢任何愿意尝试的人。这是我更改的代码部分:
async viewVideo() {
this.videoURLS = []
this.videoFiles = []
this.videoTitels = []
var storageRef = firebase.storage().ref();
var videourl = []
console.log("try")
var listRef = storageRef.child('User-Videos/');
var firstPage = await listRef.list({
maxResults: 100
});
videourl = firstPage
console.log(videourl)
if (firstPage.nextPageToken) {
var secondPage = await listRef.list({
maxResults: 100,
pageToken: firstPage.nextPageToken,
});
videourl = firstPage + secondPage
}
console.log(this.videoURLS)
if (this.videoURLS.length == 0) {
await videourl.items.map(async refImage => {
var ii = refImage.getDownloadURL()
this.videoURLS.push(ii)
})
try {
await this.videoURLS.forEach(async file => {
var fale2 = undefined
await file.then(url => {
fale2 = url.substring(url.indexOf("%") + 3)
fale2 = fale2.substring(0, fale2.indexOf("?"))
})
await db.collection("Files").doc(fale2).get().then(async data => {
file.$set('titel', await data.data().titel)
file.$set('date', await data.data().date)
if (file.$set('voted', await data.data().voted)) {
file.$set('voted', [])
}
file.$set('votes', await data.data().votes)
if (file.$set('votes', await data.data().votes)) {
file.$set('votes', 0)
}
await this.videoFiles.push(file)
this.uploadDate = data.data().date
console.log(this.videoFiles)
this.videoFiles.sort(function(a, b) {
return a.date - b.date;
})
})
})
} catch (error) {
console.log(error)
}
}
},
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
解决方案
首先,file.$set('votes', await data.data().votes)
是使用错误的语法。应该是this.$set(file, 'votes', data.data().votes)
。我猜第二个data
返回data()
一个带有投票作为属性的对象。
您在这里不需要使用 await 。await db.collection("Files").doc(fale2).get().then(async data => {....
您已经在.then
此处以块的形式使用了 Promise。异步等待和then/catch
块基本上做同样的事情。这是一个或另一个。
请查看这篇精彩的帖子,其中介绍了如何在 javascript 中处理异步代码。现在了解 javascript 的异步特性非常重要。
有很多东西可以选择,现在我的重点是从你的代码中删除多余的或可能无法使其工作的东西。我不关注逻辑。有了更多信息,我可能会对逻辑进行必要的编辑。
我会在代码中留下我觉得有必要的注释
async viewVideo() {
this.videoURLS = []
this.videoFiles = []
this.videoTitels = []
var storageRef = firebase.storage().ref();
var videourl = '' // videourl should be initialised as a string
console.log("try")
var listRef = storageRef.child('User-Videos/');
var firstPage = listRef.list({ // the await here isn't necessary as this function isn't expected to return a promise(isn't asynchronous) to the best of my knowledge.
maxResults: 100
});
videourl = firstPage
console.log(videourl)
if (firstPage.nextPageToken) {
var secondPage = listRef.list({ // same as above
maxResults: 100,
pageToken: firstPage.nextPageToken,
});
videourl = firstPage + secondPage // videourl is a string here
}
console.log(this.videoURLS)
if (this.videoURLS.length == 0) {
videourl.items.map(async refImage => { //videourl is acting as an object here (something seems off here) - please explain what is happening here
// again await is not needed here as the map function does not return a promise
var ii = refImage.getDownloadURL()
this.videoURLS.push(ii)
})
try {
this.videoURLS.forEach(file => { // await here is not necessary as the forEach method does not return a promise
// The 'async' keyword is not necessary here. It is required to use the await keyword and due to the database call here, ordinarily it wouldn't be out of place, but you deal with that bit of asynchronous code using a `.then` block. It's `async-await` or `.then` and never both.
var fale2 = undefined
file.then(url => { // await is not necessary here as you use `.then`
// Also, does `file` return a promise? That's the only thing I can infer from `file.then`. It looks odd.
fale2 = url.substring(url.indexOf("%") + 3)
fale2 = fale2.substring(0, fale2.indexOf("?"))
})
db.collection("Files").doc(fale2).get().then(data => { // await and async not necessary due to the same reasons outlined above
this.$set(file, 'titel', data.data().titel) // correct syntax according to vue's documentation - https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats
this.$set(file, 'date', data.data().date)
if (this.$set(file, 'voted', data.data().voted)) { // I don't know what's going on here, I will just correct the syntax. I am not focused on the logic at this point
this.$set(file, 'voted', [])
}
this.$set(file, 'votes', data.data().votes)
if (this.$set(file, 'votes', data.data().votes)) {
this.$set(file, 'votes', 0)
}
this.videoFiles.push(file) // await not necessary here as the push method does not return a promise and also is not asynchronous
this.uploadDate = data.data().date
console.log(this.videoFiles)
this.videoFiles.sort(function(a, b) {
return a.date - b.date;
})
})
})
} catch (error) {
console.log(error)
}
}
},
就像我在开头所说的那样,第一次尝试并不是为了让逻辑起作用。那里发生了很多我不明白的事情。我专注于删除冗余代码和纠正语法错误。如果提供更多细节,我也许可以查看逻辑。
推荐阅读
- c# - 如何使用 Emgu.CV 以 30 FPS 获得 1920*1080 作为默认值?
- mysql - mysql8 新管理员用户无法授予代理
- android - 像 WhatsApp 一样以 PIP 模式播放 YouTube 视频
- laravel-nova - Laravel Nova 多对多关系表
- java - Spring Cloud 流反序列化不同的 pojo
- r - How to align the text on the right side of the value box in R shiny?
- ios - 如何获取在 iOS Keychain 中创建和存储的密钥的唯一标识符
- image - 如何保护网站访问者的图像?
- azure - 自定义 Azure AD B2C 登录页面
- flutter - 我正在尝试运行默认的颤振应用程序,但出现错误