0

I am using oraclize-api to fetch and store twitter posts into a smart contract. Posts are placed into a mapping using the twitter id as the key (i.e. <username>/status/<id>), and the tweet text as the value.

I want my front end to display the tweet text once the oraclize __callback function has been called, and the tweet text has been saved to the smart contract.

The options have I entertained are:

  • Having a button for the user to "check the state" manually
  • Doing a loop to check for a tweet text value that is not ""

Neither are quite that good, especially the loop if there is a problem with the Oraclize, like an out of gas error where the state will never get updated.

Is there a recommended practice for this?

  • The loop seems fine to me, but how about emitting an event? – user19510 Aug 12 '18 at 20:16
  • I guess I am just a little unfamiliar with oraclize. Will there be some automatic event emitted somewhere if __callback fails? I don't want to create a loop that will never end. – Shawn Tabrizi Aug 12 '18 at 20:21
  • I imagine it's certainly possible that your callback will never be invoked (e.g. gas prices shoot way up and never come back down), so you won't be able to avoid situations where you have to use a timeout to give up on waiting. – user19510 Aug 12 '18 at 20:24
1

You could code your callback function to emit an event, then on the front-end use web3 to listen for events with that name.

So, when the callback tx is processed, the event will be emitted and if you are on the dApp listening for such events you will have the opportunity to act upon it. You don't have to do any infinite loops, just listen for the event.

If the Oraclize was not triggered for some reason, your dapp will just never receive the event, in which was I supposed you could timeout or something. If the callback was received but it reverted for some reason related to the actual code your wrote for the function, then same scenario. Though, you will be able to know it reverted and fail accordingly.

| improve this answer | |
0

I ended up doing a recursive call to an asynchronous function to support this scenario.

Something like this:

checkOracle: function (count) {
    if (count > 30) {
        App.showErrorMessage("Something went wrong with the oraclize process.");
        return;
    }

    var twitterBountyInstance;
    var tweetUrl = $('#twitter-url').val();

    if (tweetUrl.includes("https://twitter.com/")) {
        tweetId = tweetUrl.replace("https://twitter.com/", "");

        App.contracts.TwitterBounty.deployed().then(function (instance) {
        twitterBountyInstance = instance;

        return twitterBountyInstance.getTweetText(tweetId)
        }).then(function (result) {
        if (result == "") {
            App.showNormalMessage("Loading... (" + count + ")");
            setTimeout(function () {
                App.checkOracle(count + 1);
                }, 1000);
        } else {
            App.showOracleTweetText(result);
        }

        })


    } else {
        console.log("Bad URL")
    }
},

The function accepts a parameter which can be used to timeout the operation if it is taking too long.

| improve this answer | |

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.