0

I have been trying to replicate the following simple tutorial but deploying to the ropsten network using infura instead of to local host: https://medium.com/coinmonks/interacting-with-ethereum-smart-contracts-through-web3-js-e0efad17977

I am able to set the values in the deployed contract through setInstructor via my javascript code and do test gas payments using metamask and ropsten. However, when I try interact with getInstructor I get an undefined error. I have pasted my code below. I think the issue may be with the way I've constructed the promise but I am having difficultly resolving it. I am using a promise here as I have deployed to the Ropsten network and there will be a wait before the result.

my solidity contract simply sets and gets values

pragma solidity ^0.5.0;
contract Coursetro {

   string fName;
   uint age;

   function setInstructor(string memory _fName, uint _age) public {
       fName = _fName;
       age = _age;
   }

   function getInstructor() public view returns (string memory, uint) {
       return (fName, age);
   }

}

my index.hmtl file takes two inputs and displays the two inputs

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" type="text/css" href="main.css">
    <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
    <script src="bootstrap.min.js"></script>
    <script src="web3.min.js"></script>
    <script src="truffle-contract.js"></script>
    <script src="app.js"></script>
</head>
<body>
    <div class="container">
        <h1>Coursetro Instructor</h1>
        <h2 id="instructor"></h2>
        <label for="name" class="col-lg-2 control-label">Instructor Name</label>
        <input id="name" type="text">
        <label for="name" class="col-lg-2 control-label">Instructor Age</label>
        <input id="age" type="text">
        <button id="button" class="buttman">Update Instructor</button>

    </div>
</body>
</html>

my javascript file 'app.js' should set and get values in the contract but only the set works as intended, get returns undefined. The problem is in the retrieveInstructor function

  App = {
  web3Provider: null,
  contracts: {},

  init: async function() {

    return await App.initWeb3();
  },

  initWeb3: async function() {
    // Modern dapp browsers...
    if (window.ethereum) {
      App.web3Provider = window.ethereum;
      try {
        // Request account access
        await window.ethereum.enable();
      } catch (error) {
        // User denied account access...
        console.error("User denied account access")
      }
    }
    // Legacy dapp browsers...
    else if (window.web3) {
      App.web3Provider = window.web3.currentProvider;
    }
    // If no injected web3 instance is detected, fall back to Ganache
    else {
      App.web3Provider = new Web3.providers.HttpProvider('https://ropsten.infura.io/v3/[REDACTED]');
    }
    web3 = new Web3(App.web3Provider);

    return App.initContract();
  },

  initContract: function() {
    $.getJSON('Coursetro.json', function(data) {
      // Get the necessary contract artifact file and instantiate it with truffle-contract
      var CoursetroArtifact = data;
      App.contracts.Coursetro = TruffleContract(CoursetroArtifact);

      // Set the provider for our contract
      App.contracts.Coursetro.setProvider(App.web3Provider);

    });

    return App.bindEvents();
  },

  bindEvents: function() {
    $(document).on('click', ".buttman", App.handleInstructor);
  },


  handleInstructor: function(event) {
    event.preventDefault();

    var setInstructorInstance;

      App.contracts.Coursetro.deployed().then(function(instance) {
        setInstructorInstance = instance;


        return setInstructorInstance.setInstructor($("#name").val(), $("#age").val()) && App.retreiveInstructor();
      }).catch(function(err) {
        console.log(err.message);
      });


   },

   retreiveInstructor: function() {

    var getInstructorInstance;


      App.contracts.Coursetro.deployed().then(function(instance) {
        getInstructorInstance = instance;

        // Promise
            let promise = new Promise(
                    function (resolve, reject) {
                        if (getInstructorInstance.getInstructor()) {


                        resolve(true); // fulfilled
                        } else {
                        var reason = new Error('could not retrieve data');
                        reject(reason); // reject
                        }

                }
            );

        promise.then(
        function(result) { $("#instructor").html(result[0]+' ('+result[1]+' years old)'); },
        function(error) { ; }
        );  



      });
   }

};

$(function() {
  $(window).on('load', function () {
    App.init();
  });
});

May I ask what the correct way to write the web3 function to retrieve a value is?

1

I managed to resolve this by changing line

resolve(true); // fulfilled

to

resolve(getInstructorInstance.getInstructor()); // fulfilled

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.