Реакция асинхронного метода setState Переменная не устанавливается во времени - PullRequest
1 голос
/ 29 марта 2019

Я пытаюсь запустить 3 метода друг за другом, когда пользователь нажимает кнопку

Шаги:

1: отправить файл в IPFS, получить ссылку назад и назначить его переменной состояния

2: добавить эту ссылку (из этой переменной) в смарт-контракт блокчейна

3: добавить запись в базу данных firebase

Проблема в том, что ссылка IPFS является нулевой, когда я пытаюсь передать ее в свой смарт-контракт, однако после запуска метода я вижу, как ссылка выводится на консоль. Поэтому я предполагаю, что следующий метод не будет установлен вовремя, чтобы увидеть переменную.

Метод IPFS:

pushToIPFS = async(e) => {
      //  e.preventDefault()
        await ipfs.add(this.state.buffer, (err, ipfsHash) => {
            console.log(err, ipfsHash)
            //this.setState({IPFSlink : ipfsHash[0].hash})
            console.log(ipfsHash[0].hash)
            return ipfsHash[0].hash
        })
    }

Метод блокчейна:

addToBlockchain = async(e) => {
        //create a new key for our student
        var key = this.state.StudentNumber + this.state.account[0]
        key = parseInt(hash(key), 10)
        this.setState({idForBlockchain: key})
        console.log(key)

        //get todays date
        let newDate = new Date()
        newDate = newDate.getTime()
        var _ipfsLink = this.state.IPFSlink
        var _account = this.state.account[0]
        console.log(_ipfsLink)
        console.log(this.state.IPFSlink)
        await storehash.methods.sendDocument(_ipfsLink, newDate, 


    }

Метод Firebase:

createStudent = async(e) => {
        //get student details from state variables & current user uid
        var _uid = this.state.uid
        var _studentName = this.state.StudentName
        var _studentNumber = this.state.StudentNumber
        var _courseCode = this.state.CourseCode
        var _courseName = this.state.CourseName
        var _idForBlockchain = this.state.idForBlockchain

        // database.ref.students.uid.studentNumber 
        const db = firebase.database()
        db.ref().child("students").child(_uid).child(_studentNumber).set(
            {   studentName: _studentName,
                courseCode: _courseCode,
                courseName: _courseName,
                blockchainKey: _idForBlockchain 
            }
        );

        alert("Student added")

    }

Метод, который срабатывает при нажатии кнопки:

AddMyStuff = async (e) => {
        e.preventDefault()
        await this.pushToIPFS()
        await this.addToBlockchain()
        await this.createStudent()
    }

Это возвращенная ошибка, поэтому я предполагаю, что await и setState вызывают проблемы, а нужная мне переменная не устанавливается.

Необработанный отказ (ошибка): недопустимое строковое значение (arg = "_ ipfsLocation", coderType = "string", значение = null, версия = 4.0.27)

Кто-нибудь знает, как это можно решить?

1 Ответ

0 голосов
/ 30 марта 2019

вы можете преобразовать вашу pushToIPFS в обещание вместо обратного вызова и просто разрешить его при вызове.

pushToIPFS = (e) => {
    return new Promise((resolve, reject) => {
          ipfs.add(this.state.buffer, (err, ipfsHash) => {
            resolve(ipfsHash[0].hash);
        })
    });
}

А поскольку в качестве обещания вы можете использовать async/await.

AddMyStuff = async (e) => {
        e.preventDefault()
        const ipfsHash = await this.pushToIPFS();
        //you have your ipfsHash defined, you can pass it to your other methods
    }
...