2

I have a contract :

pragma solidity ^0.4.2;

import "Owned.sol";
contract SGBFactory is Owned {

    event SGBUpdate(uint sbgID, bool isCreated, string message); // isCreated = true means created, else means deleted

    string public ownerType;

    struct SGB {
        uint id;
        string latitude;
        string longitude;
        uint minBal; // should be in Wei since Solidity doesn't support floating points as of now
        string ownerType;
        uint capacity; //should also be in grams due to the same reasons as above
        address owner;
        uint fixedUnitCostPerTransaction;
    }

    SGB[] public sgbCollection;

    function SGBCreator() {
        ownerType = "COMMUNITY";
    }

    function addSGB(
        string lat,
        string lon,
        uint minBalReq,
        uint maxCapacity,
        address ownerAccount,
        uint fixedCost
    ) onlyOwner {
        uint sgbID = sgbCollection.length++; //note the postfix operator here
        sgbCollection[sgbID] = SGB(sgbID, lat, lon, minBalReq, ownerType, maxCapacity, ownerAccount, fixedCost);
          // fire up an event here
        SGBUpdate(sgbID,true, "A new SGB is created!!");
    }

    function getSGB(uint sgbid) returns (uint sbgID, string lat, string lon, uint minBal,string ownerType) {
        return(
            sgbCollection[sgbid].id,
            sgbCollection[sgbid].latitude,
            sgbCollection[sgbid].longitude,
            sgbCollection[sgbid].minBal,
            sgbCollection[sgbid].ownerType
        );
    }

    // uint maxCapacity, address owner, uint fixedCost
    // sgbCollection[sgbid].capacity,sgbCollection[sgbid].owner,sgbCollection[sgbid].fixedUnitCostPerTransaction
}

It is deployed in my private Ethereum chain. I can call getSGB() method from Truffle console and it returns value successfully.

I used the following mechanism in Truffle console:

var contract = SGBFactory.deployed();
contract.getSGB.call(1, {from: "0x85ded4eae096d15de9bee720a6e91eb28603a7e6"}, function(err, res) {
    console.log(res);
});

But when I call the same method from JS file, the method returns nothing, nor there is an error message.

SGBWatcher.js

var accounts;
var coinbase_account;

function getSGBFromFactory() {
    var sgbAdderContract = SGBFactory.deployed();
    console.log(coinbase_account);
    sgbAdderContract.getSGB.call(0, {from: coinbase_account }, function(err, res) {
        if (err != null)
            console.log(err);
        else
            console.log(res);
    });
}

window.onload = function() {
    web3.eth.getAccounts(function(err, accs) {
        if (err != null) {
            alert("There was an error fetching your accounts.");
            console.log(err);
            return;
        }

       if (accs.length == 0) {
           alert("Couldn't get any accounts! Make sure your Ethereum client is configured correctly.");
           return;
       }

       accounts = accs;
       coinbase_account = accounts[0];
   });
}

What could be the issue here? (I already have two SGBs added in the contract, so the indexes 0 and 1 as parameter should be fine.)

1
  1. You send 0 as argument in

    sgbAdderContract.getSGB.call(0,{from: coinbase_account },function(err,res){ if(err != null) console.log(err); else console.log(res); });

    Does identifier exist?

  2. Ensure you realy call getSGBFromFactory() from your JS code

  • Sorry I forgot to mention, I have already added two SGBs. It works fine when called from Truffle console, but when I try to call it from a js file in truffle, it doesnt return anything. – freerunner Mar 24 '17 at 22:20
  • @freerunner I can not see where you call getSGBFromFactory in JS code – Alexey Barsuk Mar 24 '17 at 22:42
  • I am calling it from a button onclick event in a html file. It was just one button in the page so I didnt put it here. I tried to check whether or not the function getSGBFromFactory() is called or not by putting a console.log(sgbAdderContract). It provides the ABI in console and also a RPC call is made. Yet the promise is not returned. – freerunner Mar 24 '17 at 23:22
1

Not certain this is it, but possibly.

In Truffle 0.3.x you might consider changing the contract instantiation to a callback.

Instead of

var sgbAdderContract = SGBFactory.deployed(); console.log(coinbase_account)

Consider

var sgbAdderContact;
SGBFactory.deployed(function(instance) { 
  sgbAdderContract = instance; 
  console.log(sgbAdderContract); 
});
  • Thanks for the reply @Rob. I called console.log(sgbAdderContract) in the getSGBFromFactory() function. And it is displaying the ABI just fine. So probably it's not a problem of instantiation. Its working fine on Truffle console which is why I am puzzled. – freerunner Mar 24 '17 at 23:28
1

sgbCollection(uint _idx); already exists as the getter function of SGB[] public sgbCollection;. It will return the struct SGB element values as an array in the order of the struct. Your front end only needs to map those to something meaningful if required. So getSGB is not actually required. If however there is some need of the named return parameters, then you should modify the function as constant as there is no state changes and so no need to create a transaction.

function getSGB(uint sgbid) constant returns (uint sbgID, string lat, string lon, uint minBal,string ownerType) {...}

Your JS then simply becomes sgbAdderContract.getSGB(0) or using the accessor sgbAdderContract.sgbCollection(0)

1

The solution was :

sgbAdderContract.getSGB.call(0,{from : coinbase_account}).**then**(function(result){
//do somethiing
}).catch(function(e){
// error
});

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.