Getting Errors with Solidity Contract


(Robert Wallis) #1

We are creating a dApp to be run on Ethereum. The page loads properly and the subform loads as expected. However, once the information is entered and the “submit” button is clicked, nothing happens. In our current test environment (Metamask), we expect to receive a confirmation screen for the information to be logged. Please any help you can offer would be great.
Here is the HTML:

    <!DOCTYPE html>
    <html lang="en">
     
    <head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
  <title>Rent My Place</title>
<!-- Title will appear as a tab in browser on webpage -->
  <!-- Bootstrap -->
  <link href="css/bootstrap.min.css" rel="stylesheet">

  <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
  <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
  <!--[if lt IE 9]>
  <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
  <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
  <![endif]-->

  <!-- Application -->
  <link href="css/app.css" rel="stylesheet">
  <!-- stylesheet refers to the look of the page, Font, color-->

</head>

<body>
  <div class="container">
    <!-- container that contains title panel-->
    <div class="jumbotron text-center">
<p style="font-size:80px;padding: 1em;padding-top: 10px;padding-bottom: 10px; border:10px;border-style:solid;border-color:#c3c3c3;">
      <font color = "#880015" >Rent My Place</font></p>
    </div>

    <div class="col-md-12" id="article-list">
      <div class="row">
        <div class="col-lg-12">
          <p id="account" class="welcome pull-right"></p>
          <p id="accountBalance" class="welcome pull-left"></p>
        </div>
      </div>

      <div class="row panel panel-default">
        <div class="panel-heading clearfix">
          <div class="panel-title">
            <p style="font-size:24px;padding: 1em;padding-top: 10px;padding-bottom: 10px; border:5px;border-style:solid;border-color:#c3c3c3;">
                  <font color = "#880015">Renter's Tip: </font><font color = "#000000">Inspect the property before you send money.</font><br><font color = "#880015">Landlord's Tip: </font><font color = "#000000">Meet prospective tenants in person.</font></p>
            <!-- Button that opens second window to a form to fill out-->
            <button class="btn btn-info btn-lg pull-right" data-toggle="modal" data-target="#sellArticle">Post a Rental</button>
          </div>
        </div>
        <!-- when the event button gets click, it will show the list-->
        <ul id="events" class="collapse list-group"></ul>
      </div>

      <div id="articlesRow" class="row">
        <!-- ARTICLES with pertinent item information LOAD HERE -->
      </div>
    </div>
  </div>

<!--Result that is displayed after input-->
  <div id="articleTemplate" style="display: none;">
    <div class="row-lg-12">
      <div class="panel panel-default panel-article">
        <div class="panel-heading">
          <h3 class="panel-title"></h3>
        </div>
        <div class="panel-body">
          <strong>Beds</strong>: <span class="beds"></span><br/>
          <strong>Baths</strong>: <span class="baths"></span><br/>
          <strong>Address</strong>: <span class="propaddress"></span><br/>
          <strong>Rental Price</strong>: <span class="rental_price"></span><br/>
          <strong>Description</strong>: <span class="article_description"></span><br/>
          <strong>Property is available for showing</strong>: <span class="available"></span><br/>
          <strong>Contact Email</strong>: <span class="contact_email"></span><br/>
          <!--<strong>Sold by</strong>: <span class="article-seller"></span><br/>-->
        </div>
        <div class="panel-footer">
          <button type="button" class= "btn btn-primary btn-success btn-buy" onclick="App.buyArticle(); return false;">Buy</button>
      </div>
    </div>
  </div>
</div>

  <!-- Modal form to sell an article -->
  <div class="modal fade" id="sellArticle" role="dialog">
    <div class="modal-dialog">

      <!-- Modal content-->
      <div class="modal-content">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal">&times;</button>
          <h4 class="modal-title">Rent Your Place</h4>
        </div>
        <div class="modal-body">

          <div class="row">
            <div class="col-lg-12">
              <form>
                <div class="form-group">
                  <!--NOTE: For radio buttons to work, 'name' field must match-->
                  <label for="property_type">Property Type</label>
                  <input type="text" class="form-control" id="property_type">
              <!--    <input type="radio" name="property" id="apartment" value="apartment" > Apartment-->
                <!--  <input type="radio" name="property" id="duplex" value="duplex" > Duplex-->
                  </div>
                <div class="form-group">
                  <label for="propaddress">Address</label>
                  <input type="text" class="form-control" id="propaddress" placeholder="Enter the address">
                </div>
                <div class="form-group">
                  <label for="beds">Beds</label>
                  <input type="text" class="form-control" id="beds">
                  <!--<input type="radio" name="beds" id="one" value="1"> One
                  <input type="radio" name="beds" id="two" value="2"> Two
                  <input type="radio" name="beds" id="three" value="3"> Three +-->
                </div>
                <div class="form-group">
                  <label for="baths">Baths</label>
                  <input type="text" class="form-control" id="baths">
                <!--  <input type="radio" name="baths" id="two" value="2"> Two
                  <input type="radio" name="baths" id="three" value="3"> Three +-->
                </div>
                <div class="form-group">
                  <label for="rental_price">Rent (in USD)</label>
                  <input type="text" class="form-control" id="rental_price" placeholder="$" pattern="[0-9]+([\.,][0-9]+)?">
                </div>
                <div class="form-group">
                  <label for="description">Description</label>
                  <textarea type="text" class="form-control vresize" id="description" placeholder="Describe your property" maxlength="255"></textarea>
                </div>
                <div class="form-group">
                  <label for="available"></label>
                  <input type="checkbox" name="available" value="available" id="available"> Property is available for showing
                </div>
                <div class="form-group">
                  <label for="contact_email">Contact Email</label>
                  <input type="text" class="form-control" id="contact_email" placeholder="Enter your contact email">
                </div>
              </form>
            </div>
          </div>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-primary btn-success" data-dismiss="modal" onclick="App.sellArticle(); return false;">Submit</button>
          <button type="button" class="btn" data-dismiss="modal">Close</button>
        </div>
      </div>

    </div>
  </div>

  <div id="footer" class="container">
    <nav class="navbar navbar-default navbar-fixed-bottom">
      <div class="navbar-inner navbar-content-center text-center">
        <p class="text-muted" credit><a href="http://www.axbean.com">AXbean</a> - &copy; 2018</a></p>
      </div>
    </nav>
  </div>


  <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
  <!-- Include all compiled plugins (below), or include individual files as needed -->
  <script src="js/OurRentalManualInputDataInitWeb3appMay22.js"></script>
  <script src="js/bootstrap.min.js"></script>
  <script src="js/web3.min.js"></script>
  <script src="js/truffle-contract.js"></script>

</body>

</html>

And here is the app.js called:

App = {
  web3Provider: null,
  contracts: {},
  account: 0x0,
  loading: false,

  init: function() {
    return App.initWeb3();
  },

  initWeb3: function() {
    // initialize web3
    if(typeof web3 !== 'undefined') {
      //reuse the provider of the Web3 object injected by Metamask
      App.web3Provider = web3.currentProvider;
    } else {
      //create a new provider and plug it directly into our local node
      App.web3Provider = new Web3.providers.HttpProvider('http://localhost:7545');
    }
    web3 = new Web3(App.web3Provider);

    App.displayAccountInfo();

    return App.initContract();
  },

  displayAccountInfo: function() {
    web3.eth.getCoinbase(function(err, account) {
      if(err === null) {
        App.account = account;
        $('#account').text(account);
        web3.eth.getBalance(account, function(err, balance) {
          if(err === null) {
            $('#accountBalance').text(web3.fromWei(balance, "ether") + " ETH");
          }
        })
      }
    });
  },

  initContract: function() {
    $.getJSON('OurRentalTestFromClassMay24.json', function(chainListArtifact) {
      //added May24 to json file name
      // get the contract artifact file and use it to instantiate a truffle contract abstraction
      App.contracts.OurRentalTestFromClassMay24 = TruffleContract(chainListArtifact);
      // set the provider for our contracts
      App.contracts.OurRentalTestFromClassMay24.setProvider(App.web3Provider);
      // listen to events
      App.listenToEvents();
      // retrieve the article from the contract
      return App.reloadArticles();
    });
  },

  reloadArticles: function() {
    //avoid reentry bugs
    if(App.loading){
      return;
    }
    App.loading = true;

    // refresh account information because the balance might have changed
    App.displayAccountInfo();

    var chainListInstance;

    App.contracts.OurRentalTestFromClassMay24.deployed().then(function(instance) {
      chainListInstance = instance;
      return chainListInstance.getArticlesForSale();
    }).then(function(articlesIds) {

      // retrieve the article placeholder and clear it
      $('#articlesRow').empty();

      for(var i = 0; i < articlesIds.length; i++){
        var articleId = articlesIds[i];
        chainListInstance.articles(articleId.toNumber()).then(function(article){
          App.displayArticle(article[0], article[1], article[3], article[4], article[5]);
        });
      }
      App.loading = false;

    }).catch(function(err) {
      console.error(err.message);
      App.loading = false;
    });
  },

  displayArticle: function(id, seller, beds, baths, propaddress, rental_price, description, available, contact_email){
    var articlesRow = $('#articlesRow');

    //var etherPrice = web3.fromWei(price, "ether");

    var articleTemplate = $("#articleTemplate");
    //articleTemplate.find('.panel-title').text(name);
    articleTemplate.find('.beds').text(beds);
    articleTemplate.find('.baths').text(baths);
    articleTemplate.find('.propaddress').text(propaddress);
    articleTemplate.find('.rental_price').text(rental_price);
    articleTemplate.find('.description').text(description);
    articleTemplate.find('.available').text(available);
    articleTemplate.find('.contact_email').text(contact_email);
  //  articleTemplate.find('.article_price').text(etherPrice + " ETH");
    articleTemplate.find('.btn-buy').attr('data-id', id);
    // articleTemplate.find('.btn-buy').attr('data-value', etherPrice);

    //seller
    if(seller == App.account){
      articleTemplate.find('.article-seller').text("You");
      articleTemplate.find('.btn-buy').hide();
    }else{
      articleTemplate.find('.article-seller').text(seller);
      articleTemplate.find('.btn-buy').show();
    }
    //add this new article
    articlesRow.append(articleTemplate.html());
  },

  sellArticle: function() {
    // retrieve the detail of the article
  //  var _article_name = $('#article_name').val();
    var _description = $('#description').val();
    var _beds = $('#beds').val();
    var _baths = $('#baths').val();
    var _propaddress = $('#propaddress').val();
    var _rental_price = $('#rental_price').val();
    var _property_type = $('#property_type').val();
    var _available = $('#available').val();
    var _contact_email = $('#contact_email').val();
  //  var _article_price = $('#article_price').val();
  //  var _price = web3.toWei(parseFloat($('#article_price').val() || 0), "ether");

    if((_description.trim() == '') || (rental_price == 0)) {
      // nothing to sell
      return false;
    }

    App.contracts.OurRentalTestFromClassMay24.deployed().then(function(instance) {
      return instance.sellArticle(_description, _beds, _baths, _propaddress, _rental_price, _property_type, _available, _contact_email, {
        from: App.account,
        gas: 500000
      });
    }).then(function(result) {

    }).catch(function(err) {
      console.error(err);
    });
  },

  // listen to events triggered by the contract
  listenToEvents: function() {
    App.contracts.OurRentalTestFromClassMay24.deployed().then(function(instance) {
      instance.LogSellArticle({}, {}).watch(function(error, event) {
        if (!error) {
          $("#events").append('<li class="list-group-item">' + event.args._name + ' is now for sale</li>');
        } else {
          console.error(error);
        }
        App.reloadArticles();
      });

      instance.LogBuyArticle({}, {}).watch(function(error, event) {
        if (!error) {
          $("#events").append('<li class="list-group-item">' + event.args._buyer + ' bought ' + event.args._name + '</li>');
        } else {
          console.error(error);
        }
        App.reloadArticles();
      });
    });
  },

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

    // retrieve the article price and data
    var _articleId = $(event.target).data('id');
    var _price = parseFloat($(event.target).data('value'));

    App.contracts.OurRentalTestFromClassMay24.deployed().then(function(instance){
      return instance.buyArticle(_articleId, {
        from: App.account,
        value: web3.toWei(_price, "ether"),
        gas: 500000
      });
    }).catch(function(error) {
      console.error(error);
    });
  }
};

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