DEV Community

Cover image for Creating a Promotion Tracker with React and Reloadly
fullStackMafia🀄
fullStackMafia🀄

Posted on • Updated on

Creating a Promotion Tracker with React and Reloadly

Airtime can largely be seen as a necessity in today’s world thus when making top-ups, customers are always in search of value. It would be great if an application existed where a user could check for available airtime or data bonuses and promotions in any region around the world. In this article, we’ll build an application that meets this need using React - a JavaScript framework, and Reloadly - a service for global airtime top-ups.


Tools you will need

  • Node : A back-end JavaScript runtime environment that executes JavaScript code outside a web browser.
  • npm : A package manager for Node.
  • dotenv : A module that loads environment variables from an .env file
  • axios: A promise based HTTP client for the browser and NodeJS
  • react-bootstrap: A library that renders Bootstrap components in React applications

Also, intermediate knowledge of JavaScript and React would be fundamental to digesting this tutorial.

If you want to check out the source code of this application before reading the article, you can find it here.


Creating a React application

The first step to getting started is creating a skeletal React application. The fastest way to do this is to use the create-react-app command via your terminal:

    # Create a new React application with the below command

    npx create-react-app reloadly-app

    # Navigate to the newly created React application

    cd reloadly-app

    # Launch the application on your browser

    npm start
Enter fullscreen mode Exit fullscreen mode

Note that npx on the first line is not a typo, it’s a package runner tool that comes with npm. Your new application’s folder should look somewhat like this when you are done creating it:

├── RELOADLY-APP
└── public
    ├── index.html
    ├── manifest.json
└── src
    ├── App.css
    ├── App.js
    ├── App.test.js
    ├── index.css
    ├── index.js
    ├── logo.svg
    ├── reportWebVitals.js
    ├── setupTests.js
└── .gitignore
└── package-lock.json
└── package.json
└── README.md
Enter fullscreen mode Exit fullscreen mode

When the app is launched, you should see a web page similar to the image below. At this point, all you’ll see is React’s default web page

create-react-app


Getting your Reloadly access token

To access airtime bonus information from Reloadly, you’ll need an access token. This can be gotten by signing up for an account on Reloadly and using your client credentials to make a POST request for an access token. On your Reloadly dashboard, you can view your client credentials in the Developers section as depicted below:

reloadly-dashboard

It's important to note here that your client credentials should be kept private and secure at all times. Use these credentials to make a POST request to the https://auth.reloadly.com/oauth/token URL with the following body parameters:

    {
      "client_id":"YOUR_CLIENT_ID",
      "client_secret":"YOUR_CLIENT_SECRET",
      "grant_type":"client_credentials",
      "audience":"https://topups.reloadly.com"
    }
Enter fullscreen mode Exit fullscreen mode

You can do this via ReqBin, an online testing tool for REST APIs.


Safeguarding your access token

On getting your access token, you’ll need a place to safely store it. This can be done using a .env file. First navigate to your terminal and in your project, install the dotenv module:


    npm install dotenv --save

Enter fullscreen mode Exit fullscreen mode

Once this is installed, create a .env file in your project’s root folder and store your access token in it using the format below:

    // .env

    REACT_APP_ACCESS_TOKEN=Bearer YOUR_ACCESS_TOKEN_HERE

Enter fullscreen mode Exit fullscreen mode

Fetching data with hooks and Axios

Once your access token is safely stored, you can use it to get promotion data from Reloadly’s servers. First, define the variables you will need to use as headers when making a request for the promotion data. The code snippet blow shows how to achieve this

    // src/promotions.js

    const accessToken = process.env.REACT_APP_ACCESS_TOKEN;
    const reloadlyJSON = `application/com.reloadly.topups-v1+json`
    const headers = {
      Accept: reloadlyJSON,
      Authorization: accessToken
    };
Enter fullscreen mode Exit fullscreen mode

Next, you’ll define and handle state management for various data interaction points in your application. The promotion tracker will use three variables to track its different states:

  • data : For handling the promotion information retrieved from Reloadly’s servers
  • countryCode : For handling the country ISO code inputted by a user when requesting for promotion details about a particular country
  • loading : For handling the time intervals between a request to Reloadly’s servers and a response

These states can be managed with React’s useState() hook. The code snippet blow shows how the useState() hook initializes and updates state in the data , countryCode and loading variables:

    // src/promotions.js

    const [data, setData] = useState([]);
    const [countryCode, setCountryCode] = useState("");
    const [loading, setLoading] = useState(false);
Enter fullscreen mode Exit fullscreen mode

Once this is done, you can make a GET request to Reloadly’s /promotions/country-codes endpoint with the aid of Axios. The code snippet below shows how this can be achieved by creating an asynchronous function called Promochecker() and in it, making your request:


// src/promotions.js

  const PromoChecker = async () => {
    setLoading(true);
    try {
      await axios
        .get(
          `https://topups.reloadly.com/promotions/country-codes/` + countryCode,
          {
            headers: headers
          }
        )
        .then((res) => {
          console.log(res.data)
          setData(res.data);
        });
    } catch (e) {
      setData(e.response.data);
      console.log(e.response);
    }
    setLoading(false);
  };
Enter fullscreen mode Exit fullscreen mode

Viewing an operator’s promotion data

The steps to fetching the promotion data of an operator have been outlined. However, this data needs to be displayed to users of your application. You will also need to display instructions on how to use the application. The achieve these, you will use React’s conditional rendering feature to update the UI of your application. The code snippet below shows how you render a welcome message that will be seen by your application’s users:


// src/promotions.js

return (
  <section className="instructions">
    <h1>Welcome!</h1> <br></br>{" "}
    <p>
      You can search for ongoing promotions for mobile top-ups in a country by
      using the country's Alpha 2 ISO code.
    </p>{" "}
    <br></br>
    <p>
      {" "}
      Refer to this{" "}
      <a
        href="https://www.nationsonline.org/oneworld/country_code_list.htm"
        target="_blank"
        rel="noreferrer"
      >
        page
      </a>{" "}
      for a complete directory of ISO codes.
    </p>
  </section>
);
Enter fullscreen mode Exit fullscreen mode

Next, you need to display an input form to receive country codes from users. The code snippet below shows how this can be done via an input bar that receives search queries and updates the state of the countryCode variable with them:


// src/promotions.js

<section className="input_instructions">
 <input
    type="text"
    placeholder="Enter country code..."
    onChange={(e) => setCountryCode(e.target.value)}
  />
...

</section>
Enter fullscreen mode Exit fullscreen mode

After this, you’ll create a button to handle user requests. Your button should be able to perform the following:

  • Launch a request to Reloadly’s servers ( with the PromoCheck() function )
  • Display a spinner during the intervals of making a request and getting a response from Reloadly’s servers ( with the loading variable’s state )

The code snippet below depicts how this can be achieved with React’s onClick() event handler and a ternary operator:


// src/promotions.js

<section className="input_instructions">
...

  <button className="btn" onClick={PromoChecker} disabled={loading}>
    {loading && (
      <i
        className="fa fa-refresh fa-spin"
        style={{ marginRight: "5px" }}
      />
    )}
    {loading && <Spinner animation="border" />}
    {!loading && <span>Search</span>}
  </button>
</section>
Enter fullscreen mode Exit fullscreen mode

Basically, your home page should have the structure below ( excluding the styling ) when you are done:

promotion-tracker-page

To display the information on promotions received as a response, you’ll create an arrow function that maps through the promotion information in the data variable. The code snippet below shows how to achieve this using React Bootstrap components:


// src/promotions.js

<section className="response">
  {data.map((item) => (
    <Accordion key={item.id}>
        <Card className="response_card">
            <Accordion.Toggle as={Card.Header} eventKey={item}>
                {item.title} <b>&nbsp; &nbsp; &#8693;</b>
            </Accordion.Toggle>
            <Accordion.Collapse eventKey={item}>
                <Card.Body>
                  <p>{item.denominations}</p>
                  <p dangerouslySetInnerHTML={{ __html: item.description }}></p>
                  <p>{item.startDate}</p>
                  <p>{item.endDate}</p>
              </Card.Body>
            </Accordion.Collapse>
        </Card>
    </Accordion>
  ))}
</section>
Enter fullscreen mode Exit fullscreen mode

The key components of your application are all put up together now. Let’s take a look at how it works when a user makes a request.


Summary

Working with React Hooks provides a feasible way to handle data across different components. With Reloadly’s REST API, you can retrieve data on telecom operators to meet your specific use case as shown in this article. You can check out the live demo of this application here.

Discussion (2)

Collapse
umoren profile image
Umoren Samuel • Edited on

Awesome article.
I think it's also great for React beginners.
Can you briefly explain what <p dangerouslySetInnerHTML={{ __html: item.description }}></p> does?
most especially the dangerouslySetInnerHTML

Thanks

Collapse
fullstackmafia profile image
fullStackMafia🀄 Author

Hi Umoren,

I'm glad you liked my article. So the dangerouslySetInnerHTML element is used to replace inner HTML in the browser DOM. It comes in handy when you have response data from an API that also has HTML tags attached to it. I hope this answers your question. You can read more about it here:

reactjs.org/docs/dom-elements.html...