Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

116
Views
Using a Promise to check if a new random number has been generated

I'm using Chainlink Oracles to get random numbers. This process of getting a random number takes a while. In order to do that, I have to execute this line (asynchronous call), which calls a function of my smart contract an stores the new random number:

const newRandomNumber = await contract.connect(signer).randomResult(); 

What I want is to automate this process: when a new number is generated (and it is available for use), I would like to display a message to the user (in my fronted).

Hey, a new number has been generated.

How could I periodically check if the result stored in newRandomNumber has changed? And how could I display a message when that has happened?

about 4 years ago · Santiago Trujillo
2 answers
Answer question

0

tl;dr

Create an Observable to periodically call an API-endpoint:

import { distinctUntilChanged, switchMap, timer } form 'rxjs'; /* Use RxJS library for convenience */

const getRandomNumber = contract.connect(signer).randomResult();

const observable = timer(0, 1000) /* Trigger now and each 1000 ms */
    .pipe(
        switchMap(getRandomNumber), /* On each run, get the current number */
        distinctUntilChanged(), /* Only trigger subscribers if new number */
    )

const subscription = observable.subscribe((number) => console.log(number));

/* Don't forget to unsubscribe after, e.g. when the component unmounts */
subscription.unsubscribe();

Long version

The observer pattern allows you to receive notifications (e.i. 'subscribe') to multiple asynchronous events - the same way a javascript Promise notifies you after a single asynchronous event finished. (Observers are actually much more flexible than that, this is merely one usecase)

A naive javascript implementation

Let's see how we could implement your desired behavior in basic javascript

let currentRandomNumber = null;
let isCanceled = false;

async function checkAndUpdateNumber() {
  while (!isCanceled) {
    /* Set your new (or same) number */
    currentRandomNumber = await contract.connect(signer).randomResult();

    /* Wait 1000ms */
    await new Promsie((resolve) => setTimeout(resolve, 1000));
  }
}
checkAndUpdateNumber();

/* If you want to stop the loop */
isCancelled = true;

This implementation works but leaves much room for improvement. The code is not reusable in the slightest and is not easily testable.

Observers provide you with a much cleaner interface to handle multiple asynchronous operations. Check out this article to get an idea of how observers work under the hood.

The go-to javascript library for observables is RxJS. It is well tested and provides countless utility methods so I'd highly recommend you to check it out.

about 4 years ago · Santiago Trujillo Report

0

Because you tagged React on your question, here's a commented example using React state:

<div id="root"></div><script src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script><script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js"></script><script src="https://unpkg.com/@babel/standalone@7.16.6/babel.min.js"></script>
<script type="text/babel" data-type="module" data-presets="env,react">

const {useEffect, useState} = React;

// simulate making a network request to get a random number from an API:
// it will return a promise which will (at some point in the future)
// resolve with the random number, or reject with an Error
function mockFetchRandomNumber () {
  const randomNumber = Math.floor(Math.random() * 1000) + 1; // 1-1000
  const delay = Math.floor(Math.random() * 1000) + 1000; // 1-2s
  const chance = 0.2; // percent chance of random network failure
  return new Promise((resolve, reject) => setTimeout(() => {
    if (chance > Math.random()) reject(new Error('Network error'));
    else resolve(randomNumber);
  }, delay));
}

// a custom hook to wrap the logic of fetching the random number
// and maintain the state of the request while doing so
function useRandomNumber () {
  const [data, setData] = useState(); // the potential data
  const [error, setError] = useState(); // a potential error
  const [isLoading, setIsLoading] = useState(false); // whether the request is still pending
  const [reloadBoolean, setReloadBoolean] = useState(false);

  useEffect(() => {
    const fetchData = async () => {
      setIsLoading(true);
      setData(undefined);
      setError(undefined);
      try {
        const randomNumber = await mockFetchRandomNumber();
        setData(randomNumber);
        setError(undefined);
      }
      catch (ex) {
        setError(ex instanceof Error ? ex : new Error(String(ex)));
        setData(undefined);
      }
      setIsLoading(false);
    };
    fetchData();
  }, [reloadBoolean, setData, setError, setIsLoading]);

  return {
    data,
    error,
    isLoading,
    // will toggle the value of `reloadBoolean`, forcing a re-render
    reload: () => setReloadBoolean(b => !b),
  };
}

function Example () {
  const {data, error, isLoading, reload} = useRandomNumber();
  return (
    <div>
      {
        isLoading
          ? (<div>Loading random number...</div>)
          : null
      }
      {
        error
          ? (<div>There was an error loading the data ({error.message})</div>)
          : null
      }
      {
        data
          ? (<div>The random number is: {data}</div>)
          : null
      }
      <button onClick={reload}>Get new number</button>
    </div>
  );
}

ReactDOM.render(<Example />, document.getElementById('root'));

</script>

about 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!