1

I have a website where users can sell articles which will be saved into the ethereum blockchain. On that website the top looks as following:

<div id="recentArticles"></div>

The contract includes following (I wrote just the important parts):

struct Article {
    address seller;
    uint bid;
    uint bidder;    
}

Article[] articles;

function getArticle(uint _id) returns(address seller, uint bid, uint bidder){
    return(articles[_id].seller,articles[_id].bid,articles[_id].bidder);
}

function getArticlesAmount() returns(uint amount) {
    return articles.length;
}

The javascript code:

function initiateArticles() {
    contract.getArticleAmount({from: web3.eth.accounts[0]},function(error, result)
    {
        if(!error)
        {
            i = 0;
            while(i <= result) {
                getArticle(i)
                i++;
            }
        }
        else {
            console.log(error);
        }
    });
}

function getArticle(id) {
    contract.getArticle(id, {from: web3.eth.accounts[0]},function(error, result)
    {
        if(!error)
        {
            document.getElementById("recentArticles").innerHTML = document.getElementById("recentArticles").innerHTML + result[0] + result[1]...;
            ## This is not the finished code. Here I need help.
        }
        else {
            console.log(error);
        }
    });
}

document.onload = initiateArticles();

Now I want the following: When a user visits the website, it should make a call to the contract to load the 10 recent articles and show them into the div "recentArticles". That's easy and I did that successfully. But now comes the part where I need help.

I want, that every second another call is made to the contract to get the latest values of the 10 called articles.

Example: User comes to the site and views it. It loaded the last 10 articles. Someone bidded on an article. The article in the div should now show the new bid.

Whats the best way to make a function that makes a call every second for each article? I would need 10 "updaters/countdowns".

Thank you very much for answers.

  • Asking for a value does not need gas. Its basicly just a request to getArticle. – dkb Jun 13 '18 at 13:59
1

This can be done from javascript, using either setInterval(), or setTimeout():

If you don't care if the code within the timer may take longer than your interval, use setInterval():

setInterval(function_that_checks_the_price_for_a_product, delay)

That fires the function passed in as first parameter over and over.

A better approach is, to use setTimeout along with a self-executing anonymous function:

(function(){
    // do some stuff
    setTimeout(arguments.callee, 15000); //execute itself every 15 seconds - the avg block time on ethereum
})();

that guarantees, that the next call is not made before your code was executed. I used arguments.callee in this example as function reference. It's a better way to give the function a name and call that within setTimeout because arguments.callee is deprecated in ecmascript 5.

Using setInterval(), your initiateArticles() function would look like this:

function initiateArticles() {
    contract.getArticleAmount({from: web3.eth.accounts[0]},function(error, result)
    {
        if(!error)
        {
            i = 0;
            while(i <= result) {
                //need a wrapper anonymous function so we can send the i param to getArticle()
                setInterval(getArticle.bind({articleId: i}), 15000);
                i++;
            }
        }
        else {
            console.log(error);
        }
    });
}

and also change the function getArticle() to:

function getArticle() {
    const id = this.articleId;
    contract.getArticle(id, {from: web3.eth.accounts[0]},function(error, result)
    {
        if(!error)
        {
            document.getElementById("recentArticles").innerHTML = document.getElementById("recentArticles").innerHTML + result[0] + result[1]...;
            ## This is not the finished code. Here I need help.
        }
        else {
            console.log(error);
        }
    });
}
| improve this answer | |
  • Thank you for the comment, seems like we come closer to it. What I do is sending a request to getArticlesAmount which gives me for example 559 if there are 559 articles. To get now the latest 10, I make a while loop until I get the articles from id 549 to 559. Then I call getArticlesAmount with the id within the while loop. What's the best way now to intergrate your idea with the timeout or interval? – dkb Jun 13 '18 at 14:05
  • I think you meant to say you call getArticle( _id ) from within your loop. Can you put here the line where you call getArticle( _id )? – Tudor Constantin Jun 13 '18 at 14:12
  • Sorry! I forgot to add the javascript code I use. I have now added it. – dkb Jun 13 '18 at 14:23
  • I've updated my answer. Hope it solves your issue – Tudor Constantin Jun 13 '18 at 14:40
  • 1
    Thank you very much again. It helped a lot and I can solve my problems now. Really happy for the solution! – dkb Jun 14 '18 at 0:58

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.