You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决dapp报错:Cannot read properties of undefined (reading 'getMood')

解决Goerli测试网Dapp调用getMood时的TypeError问题

问题分析

报错skeleton.html:115 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'getMood')的核心原因是:页面加载后,用户未完成钱包授权(异步流程eth_requestAccounts还未执行完毕)就点击操作按钮,此时MoodContract合约实例还未被赋值,处于undefined状态。

此前问题偶发是因为用户可能在钱包授权完成后才点击按钮,近期必现则是由于用户操作更快,或钱包/网络响应变慢,导致授权流程未完成就触发了合约方法调用。

解决方案

1. 方法调用前增加实例检查

修改getMood和setMood函数,先判断合约实例是否初始化完成,未完成则提示用户等待:

async function getMood(){
    if (!MoodContract) {
        alert("请先完成钱包授权,等待初始化完成后再操作");
        return;
    }
    var getMoodPromise = MoodContract.getMood();
    var mood= await getMoodPromise;
    console.log(mood);
}

async function setMood(){
    if (!MoodContract) {
        alert("请先完成钱包授权,等待初始化完成后再操作");
        return;
    }
    var mood= document.getElementById("mood").value;
    var setMoodPromise = MoodContract.setMood(mood);
    await setMoodPromise;
}

2. 按钮状态联动初始化流程

先将按钮设为禁用状态,等合约实例初始化完成后再启用,从根源避免误操作:

  • 给按钮添加ID并设置禁用属性:
<button id="getMoodBtn" onclick="getMood()" disabled>Get Mood</button>
<button id="setMoodBtn" onclick="setMood()" disabled>Set Mood</button>
  • 在合约初始化完成后启用按钮,并处理授权失败的情况:
provider.send("eth_requestAccounts", []).then(() => {
    provider.listAccounts().then(function(accounts) {
        signer = provider.getSigner(accounts[0]);
        MoodContract = new ethers.Contract(MoodContractAddress, MoodContractABI, signer);
        // 启用操作按钮
        document.getElementById("getMoodBtn").disabled = false;
        document.getElementById("setMoodBtn").disabled = false;
    });
}).catch(err => {
    console.error("钱包授权失败:", err);
    alert("钱包授权失败,请重试");
});

3. 优化异步流程写法(可选)

用async/await替代嵌套then,让代码更易读且逻辑更清晰:

async function initContract() {
    try {
        await provider.send("eth_requestAccounts", []);
        const accounts = await provider.listAccounts();
        signer = provider.getSigner(accounts[0]);
        MoodContract = new ethers.Contract(MoodContractAddress, MoodContractABI, signer);
        // 启用按钮
        document.getElementById("getMoodBtn").disabled = false;
        document.getElementById("setMoodBtn").disabled = false;
    } catch (err) {
        console.error("初始化失败:", err);
        alert("初始化失败,请检查钱包连接或重试");
    }
}

// 页面加载后自动执行初始化
window.onload = initContract;

内容的提问来源于stack exchange,提问作者Coding_templar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 06:25:20