1
votes

So, I am currently developing a back-end and a front-end to a dApp.

The back-end is my Solidity-written smart contract, which works perfectly fine when I use and test it on Truffle. I've created a struct, and in the contract I use a list of this struct.

struct Offre {
    address manager;
    string content;
    uint number;
}

Offre[] public offres;

One of my function returns the content of any given element of this list.

function getOfferNumber(uint i) public view returns (string r) {
        return offres[i].content;
}

So, I've tested this function in Truffle and, as expected, it returns the string I want it to return.

Now, I am trying to create a button in React where I can : indicate a number i, click the button to get the content of the offer number i.

In my App.js, I have my state :

state = {
        ...
        number: '',
        offerToCheck: '',
    };

The function I'm calling with my button goes like this

checkMessage() {
        const offerToCheck = DemandeOffre.methods.getOfferNumber(this.state.number).call();
        this.setState({ offerToCheck });
    }

where this.state.number is the number I am giving him in the render():

 <div>
            <label>Check Offer</label>
                <input
                    value={this.state.number}
                    onChange={event => this.setState({ number: event.target.value })}
                />
         </div>
         <button onClick={this.checkMessage}>Check</button>
         <p> The offer you checked goes as follows : {this.state.offerToCheck}. </p>

When I try to use it like that, I get an "TypeError: this is undefined" error by React on the const offerToCheck = DemandeOffre.methods.getOfferNumber(this.state.number).call(); line.

I've tried various thing, like for example using a bind(this). When I do this, clicking on the button simply gets me to a blank page.

I am not really familiar with react, so I don't know if I've explained my problem thoroughly. Hope I will find a solution.

1
you should use <button onClick={this.checkMessage.bind(this)}>Check</button>. The reason it displays a blank page on click i think is a different issue. It has to do with DemandeOffre.methods.getOfferNumber(this.state.number).call(); - Nikos M.

1 Answers

0
votes

In order for this to not be undefined you can define the function like so:checkMessage = () => {...}. Also, the call to the contract returns a promise so to get the value from there you have to use await or .then(), you can read more here. The way you do it now the offerToCheck variable will not have the correct value when you use it to set the state of the component.