I know its a long post and thanks in advance to everyone that spends the time to read it.
We are building a Dapp called Forest. The idea is that it asks you if you are a producer or a customer and then if you pick producer it asks you to register a tree, but if you choose customer it asks you to give the dna code of a tree and then retrieves and dispaly the information if a tree with that dna has been registered. Everything works fine except that I cant make information to appear on the screen in the final stage.
*The output(Information) appears in the console, but not in the webpage!
Im showing my solidity file, my app.js and html.
Here is my solidity code:
pragma solidity ^0.5;
contract Forest {
string public name;
uint public treeCount = 0;
mapping(string => Tree) private trees;
//UserType public userType;
enum UserType {Producer, Customer}
struct Tree {
string dna;
string country;
int256 latitude;
int256 longitude;
string treeType;
}
event TreeRegistered(
string dna,
string country,
int256 latitude,
int256 longitude,
string treeType
);
constructor() public {
name = "Tree Identification";
}
function registerTree(
string memory _dna,
string memory _country,
int256 _latitude,
int256 _longitude,
string memory _treeType
) public {
// Make sure all information are filled correctly
require(bytes(_dna).length > 0, "DNA code must not be empty");
require(bytes(_country).length > 0, "Country must not be empty");
require(_latitude != 0 && _longitude != 0, "Latitude and longitude must be provided");
require(bytes(_treeType).length > 0, "Tree type must not be empty");
// Check if the DNA code is already used for a registered tree
require(trees[_dna].latitude == 0 && trees[_dna].longitude == 0, "DNA code already used for a registered tree");
//Tree count
treeCount ++;
//Register Tree
trees[_dna] = Tree(_dna, _country, _latitude, _longitude, _treeType);
//Triger Event
emit TreeRegistered(_dna, _country, _latitude, _longitude, _treeType);
}
//function setUserType(UserType _userType) public {
// userType = _userType;
//}
function getTreeInformation(string memory _dna) public view returns (string memory, string memory, int256, int256, string memory) {
// Find the tree
Tree memory _tree = trees[_dna];
// Return tree information
return (_tree.dna, _tree.country, _tree.latitude, _tree.longitude, _tree.treeType);
}
}
Here is my app.js
App = {
web3Provider: null,
contracts: {},
account: '0x0',
userType: null, // Add userType property
// Add UserType enum definition
UserType: {
Producer: "producer",
Customer: "customer"
},
init: function() {
return App.initWeb3();
},
initWeb3: function() {
if (typeof web3 !== 'undefined') {
// If a web3 instance is already provided by MetaMask.
App.web3Provider = web3.currentProvider;
web3 = new Web3(web3.currentProvider);
} else {
// Specify default instance if no web3 instance provided
App.web3Provider = new Web3.providers.HttpProvider('http://localhost:9545');
web3 = new Web3(App.web3Provider);
}
return App.initContract();
},
initContract: function() {
$.getJSON("Forest.json", function(forest) {
// Instantiate a new truffle contract from the artifact
App.contracts.Forest = TruffleContract(forest);
// Connect provider to interact with contract
App.contracts.Forest.setProvider(App.web3Provider);
return App.render();
});
},
render: function() {
var forestInstance;
var loader = $("#loader");
var content = $("#content");
var userTypeSelector = $("#userTypeSelector");
var userTypeForm = $("#userTypeForm");
loader.show();
content.hide();
// Load account data
web3.eth.getCoinbase(function(err, account) {
if (err === null) {
App.account = account;
$("#accountAddress").html("Your Account: " + account);
}
});
// Show user type selection form
userTypeForm.show();
// Handle user type selection
userTypeSelector.on("submit", function(event) {
event.preventDefault();
var selectedUserType = $("input[name=userType]:checked").val();
if (selectedUserType === App.UserType.Producer) {
App.userType = App.UserType.Producer;
App.registerTree();
} else if (selectedUserType === App.UserType.Customer) {
App.userType = App.UserType.Customer;
App.getTreeInformation();
} else {
console.log("Invalid user type. Please try again.");
}
});
// Get tree count and display it
App.contracts.Forest.deployed().then(function(instance) {
forestInstance = instance;
return forestInstance.treeCount();
}).then(function(count) {
$("#treeCount").html("Tree Count: " + count.toNumber());
}).catch(function(error) {
console.error('Error getting tree count:', error);
});
loader.hide();
content.show();
},
handleUserType: function() {
var selectedUserType = $("#userTypeSelect").val();
if (selectedUserType === "Producer") {
App.userType = App.UserType.Producer;
$("#producerForm").show();
$("#customerForm").hide();
$("#treeInfo").empty();
} else if (selectedUserType === "Customer") {
App.userType = App.UserType.Customer;
$("#customerForm").show();
$("#producerForm").hide();
$("#treeInfo").empty();
} else {
console.log("Invalid user type. Please try again.");
}
},
registerTree: function() {
// Get the required inputs from the user (DNA, country, latitude, longitude, tree type)
var dna = $("#dnaInputProducer").val();
var country = $("#countryInput").val();
var latitude = parseFloat($("#latitudeInput").val());
var longitude = parseFloat($("#longitudeInput").val());
var treeType = $("#treeTypeInput").val();
App.contracts.Forest.deployed().then(function(instance) {
return instance.registerTree(dna, country, latitude, longitude, treeType, { from: App.account });
}).then(function(result) {
console.log('Tree registered successfully!');
console.log('Transaction Hash:', result.tx);
// Display success message on the page
$("#successMessage").text('Success');
$("#successMessage").show();
// Bind a click event to the document to hide the success message when clicked
$(document).on('click', function() {
$("#successMessage").hide();
// Unbind the click event after it's triggered once
$(document).off('click');
});
}).catch(function(error) {
console.error('Error registering tree:', error);
// Display the error message on the page
$("#errorMessage").text(error.message);
$("#errorMessage").show();
});
},
getTreeInformation: function() {
// Get the required input from the user (DNA)
var dna = $("#dnaInputCustomer").val();
App.contracts.Forest.deployed().then(function(instance) {
return instance.getTreeInformation(dna);
}).then(function(treeInfo) {
if (treeInfo[0] === "") {
// Display failure message if DNA is not found
$("#failureMessage").text('DNA not found');
$("#failureMessage").show();
// Bind a click event to the document to hide the failure message when clicked
$(document).on('click', function() {
$("#failureMessage").hide();
// Unbind the click event after it's triggered once
$(document).off('click');
});
} else {
console.log('Tree Information:');
console.log('DNA:', treeInfo[0]);
console.log('Country:', treeInfo[1]);
console.log('Latitude:', treeInfo[2]);
console.log('Longitude:', treeInfo[3]);
console.log('Tree Type:', treeInfo[4]);
// Display the tree information on the page
$("#treeInfo").show();
$("#dnaOutput").text('DNA: ' + treeInfo[0]);
$("#countryOutput").text('Country: ' + treeInfo[1]);
$("#latitudeOutput").text('Latitude: ' + treeInfo[2]);
$("#longitudeOutput").text('Longitude: ' + treeInfo[3]);
$("#treeTypeOutput").text('Tree Type: ' + treeInfo[4]);
// Hide the failure message (if shown)
$("#failureMessage").hide();
}
}).catch(function(error) {
console.error('Error getting tree information:', error);
});
}
};
$(function() {
$(window).load(function() {
App.init();
});
});
$(document).ready(function() {
// Set form references
App.userTypeForm = $("#userTypeForm");
App.producerForm = $("#producerForm");
App.customerForm = $("#customerForm");
App.treeInfo = $("#treeInfo");
// Hide the producer and customer forms initially
App.producerForm.hide();
App.customerForm.hide();
// Add event listener to the user type form
App.userTypeForm.on("submit", function(event) {
event.preventDefault();
var userType = $('input[name=userType]:checked', '#userTypeForm').val();
if (userType === "producer") {
// Show the producer form
App.producerForm.show();
App.customerForm.hide();
App.treeInfo.empty();
} else if (userType === "customer") {
// Show the customer form
App.customerForm.show();
App.producerForm.hide();
App.treeInfo.empty();
}
});
});
//ENABLES METAMASK LOGIN
const ethEnabled = async () => {
if (window.ethereum) {
await window.ethereum.request({ method: "eth_requestAccounts" });
window.web3 = new Web3(window.ethereum);
return true;
}
return false;
};
login = function() {
if (!ethEnabled()) {
alert("Please use an Ethereum-compatible browser or install an extension like MetaMask to use this dApp");
} else {
App.init();
}
};
and here is my 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">
<title>Forest DAPP</title>
<!-- Bootstrap -->
<link href="css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container" style="width: 650px;">
<div class="row">
<div class="col-lg-12">
<h1 class="text-center">Forest DAPP</h1>
<hr/>
<br/>
<div id="loader">
<p class="text-center">Loading...</p>
</div>
<div id="content" style="display: none;">
<div id="userTypeForm">
<div class="form-group">
<label for="userTypeSelect">Select User Type</label>
<select class="form-control" id="userTypeSelect">
<option value="Producer">Producer</option>
<option value="Customer">Customer</option>
</select>
</div>
<button type="button" class="btn btn-primary" onclick="App.handleUserType()">Submit</button>
</div>
<div id="producerForm" style="display: none;">
<form id="producerForm" onSubmit="App.registerTree(); return false;">
<div class="form-group">
<label for="dnaInputProducer">DNA</label>
<input type="text" class="form-control" id="dnaInputProducer" placeholder="Enter DNA">
</div>
<div class="form-group">
<label for="countryInput">Country</label>
<input type="text" class="form-control" id="countryInput" placeholder="Enter Country">
</div>
<div class="form-group">
<label for="latitudeInput">Latitude</label>
<input type="text" class="form-control" id="latitudeInput" placeholder="Enter Latitude">
</div>
<div class="form-group">
<label for="longitudeInput">Longitude</label>
<input type="text" class="form-control" id="longitudeInput" placeholder="Enter Longitude">
</div>
<div class="form-group">
<label for="treeTypeInput">Tree Type</label>
<input type="text" class="form-control" id="treeTypeInput" placeholder="Enter Tree Type">
</div>
<button type="submit" class="btn btn-primary">Register Tree</button>
</form>
</div>
<div id="customerForm" style="display: none;">
<form id="customerForm" onSubmit="App.getTreeInformation(); return false;">
<div class="form-group">
<label for="dnaInputCustomer">DNA</label>
<input type="text" class="form-control" id="dnaInputCustomer" placeholder="Enter DNA">
</div>
<button type="submit" class="btn btn-primary">Get Tree Information</button>
</form>
</div>
<div id="treeInfo" style="display: none;">
<h3>Tree Information</h3>
<p id="dnaOutput"></p>
<p id="countryOutput"></p>
<p id="latitudeOutput"></p>
<p id="longitudeOutput"></p>
<p id="treeTypeOutput"></p>
</div>
<div id="treeCount"></div>
<div id="successMessage" class="alert alert-success" style="display: none;"></div>
<div id="failureMessage" class="alert alert-failure" style="display: none;"></div>
</div>
</div>
</div>
</div>
<style>
.alert-success {
margin-top: 10px;
padding: 10px;
}
</style>
<style>
.alert-failure {
margin-top: 10px;
padding: 10px;
}
</style>
<!-- button necessary to connect Metamask to port-->
<button class="btn btn-primary btn-l pull-right" style="margin-top: 30px;" onclick="login()">
<span class="glyphicon glyphicon-user"></span> CONNECT METAMASK</button>
<!-- 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/bootstrap.min.js"></script>
<script src="js/web3.min.js"></script>
<script src="js/truffle-contract.js"></script>
<script src="js/app.js"></script>
</body>
</html>
Please make any suggestions.