How to build a sports prediction application on the steem blockchain using Node/ExpressJS - 3

in #utopian-io5 years ago (edited)

Repository

https://github.com/nodejs/node

What Will I Learn?

This post contains the third part in a series of tutorials on how you can build a prediction app that allows users to predict the outcome of sport events and post their predictions on the steem blockchain.

See the links to the earlier posts in the series at the end of this post.

The application we'll be building will have the following features.

  • Users will be able to login using their steem account credentials.

  • A page for creating prediction tickets

  • User dashboard for viewing prediction tickets by the user and other users

  • Steem Wallet that allows users to transfer funds

  • User Profile Page

In the introduction post we covered the user authentication aspect of the app by adding a login page where users can login with their steem username and password.

In the last tutorial we created an authentication guard that prevents users form accessing protected pages when they are not logged in.

In this post, we'll be working on the dashboard where we'll be adding several components that will allow us to view a list of sport events slated to occur on a particular day for all sports and a selected sport.

Requirements

In order to be able to follow this tutorial the user has to be able to use the following

  • HTML/CSS
  • JavaScript/JQuery
  • TheSportsDB public api
  • AxiosJS
  • NodeJS/Express
  • SteemJS Api

Difficulty

Basic

Tutorial Content

Last week I wrote a tutorial on how to retrieve and display sports data from TheSportsDB API.

If you have previously read that tutorial then this post might seem a bit identical as they both some similarities, however, you can view this tutorial as a more extensive and detailed version of that post.

List of All Sports In a Sidebar

First thing we'll be doing here is to list all sports stored in the database in a sidebar. To do that we need to firstly go to our project directory, start up our backend server and open dashboard.html.

We need to include MaterializeCSS in dashboard.html, add MaterializeCSS through cdn by adding the following code to the file

For JavaScript

<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>

For CSS

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">

In dashboard.html below the <section class="banner"></section> tag, add the code

<section class="sports-area">
        <ul id="all-sports-list"></ul>
</section>

In dashboard.js add the following code in order to send request for our desired data, retrieve the data and display it on the dashboard.

axios.get('https://www.thesportsdb.com/api/v1/json/1/all_sports.php').then(response => {
        const responseArray = response.data.sports;

        let allSports = ``;

        responseArray.forEach(sport => {
            const sportName = sport.strSport

            const collectionItem = `<li class="list-item" onclick="viewLeagues()">${sportName}</li>`

            allSports = allSports + collectionItem;
        })

        document.getElementById('all-sports-list').innerHTML = allSports;
    }).catch(err => {
        console.log(err)
    })

After saving and reloading the page, we should have something like this on our interface

steempredict-13.PNG

We want to make it so that whenever a user clicks on any of the sports in the list above a list will appear showing all events/games/matches under that particular sport set to occur in the next 24 hours.

Display all Upcoming Events Under A Particular League

This section is an extension of the first section as we'll be using the data pulled from the last section to display all we need to display in this section.

In this section, we want to make it so that when any of the sports listed on the sidebar is clicked, the interface will display a list of events that will occur in the next 24 hours for that sport and the league the event belongs to.

In dashboard.js on the line

const collectionItem = `<li class="list-item" onclick="viewLeagues()">${sportName}</li>`.

You'll notice that the <li> tag has an attribute with value onclick="viewLeagues()".

viewLeagues() is the function that will help us send a request that will return the list of all events set to happen in .the next 24 hours

In dashboard.js, add the code below to retrieve and display all leagues under a particular sport

function viewLeagues() {
    const allLeagues = [];

    $( "#eventsView" ).html('<tr></tr>');

    $('.list-item').on('click', function(event) {
        event.preventDefault();
        $('.list-item').off('click');
        const sportName = $(this).text();
        const sportNameSlug =  sportName.replace(/ /g, '%20');

        console.log(sportName)

        axios.get(`https://www.thesportsdb.com/api/v1/json/1/search_all_leagues.php?&s=${sportNameSlug}`).then(response => {
            const responseArray = response.data.countrys;

            responseArray.forEach(oneresponse => {
                allLeagues.push(oneresponse)
            })
            
        }).then(function() {
            allLeagues.forEach(league => {

                let tomorrowFixtures = ``;
                const tomorrowDate = new Date()

                tomorrowDate.setDate(tomorrowDate.getDate() + 1);

                const tomorrowDateInit = tomorrowDate.getDate();

                const tomorrowMonthNum = tomorrowDate.getMonth() + 01;

                const tomorrowMonthStr = '0' + tomorrowMonthNum

               let tomorrowDayStr = '0' + tomorrowDate.getDate();

                if (tomorrowDayStr.length > 2) {
                    tomorrowDayStr = tomorrowDayStr.substr(1);
                }

                const tomorrowDateNum = tomorrowDate.getFullYear() + '-' + tomorrowMonthStr + '-' + tomorrowDayStr

                const leagueName = league.strLeague;

                const leagueNameHTML = `<h3 class ="league-name">${leagueName}</h3>`
                
                const leagueNameSlug =  leagueName.replace(/ /g, '_')

                axios.get(`https://www.thesportsdb.com/api/v1/json/1/eventsday.php?d=${tomorrowDateNum}&l=${leagueNameSlug}`).then(response => {
                    const tomorrowEvents = response.data.events;

                    let eventHTML = ``;

                    if (tomorrowEvents === null) {
                        $( "#eventsView" ).append( `<tr class="white-text no-event"><td>No ${leagueName} events tomorrow</td><td>${leagueName}</td><td>${sportName}</td></tr>` );
                    }

                    if (tomorrowEvents !== null) {
                        tomorrowEvents.forEach(event => {
                            const eventName = event.strEvent;

                            const leagueNameLower = leagueNameSlug.toLowerCase();
    
                            const eventNameHTML= `<tr class="white-text one-event"><td><b>${eventName}</b></td><td><b>${leagueName}</b></td><td><b>${sportName}</b></tr>`
    
                            tomorrowFixtures = tomorrowFixtures + eventNameHTML
                        })
                    }
                    
            $( "#eventsView" ).append(tomorrowFixtures);
            event.stopImmediatePropagation();
                }).catch(err => {
                    console.log(err);
                })
            })
        });
    })
}

The function above contains two http requests working hand in hand to populate the interface. The first request returns a list of all leagues/competition under any supplied sport.

The second picks each league in the array storing the response to the first request and return a list of events set to occur in that competition in the next 24 hours.

And it also indicates if there are no events holding in the next 24 hours.

Webp.net-gifmaker (30).gif

Display Upcoming Events Upon Page Load

When the page loads, by default we want to display a list of all events happening in the next 24 hours regardless of the sport or competition.

To do that we need to edit our dashboard.html file and add the following code as an attribute inside the opening <body> tag to make it look like

 <body onload="displayTomorrowEvents()">

The code above simply tells the file that once the page loads the function displayTomorrowEvents() should run.

function displayTomorrowEvents() {
    
    console.log('Getting Events')

    let upcomingFixtures = ``;

    const upcomingDate = new Date();

    upcomingDate.setDate(upcomingDate.getDate() + 1);

    const upcomingMonthNum = upcomingDate.getMonth() + 01;

    const upcomingMonthStr = '0' + upcomingMonthNum

    let upcomingDayStr = '0' + upcomingDate.getDate();

    if (upcomingDayStr.length > 2) {
        upcomingDayStr = upcomingDayStr.substr(1);
    }

    const upcomingDateNum = upcomingDate.getFullYear() + '-' + upcomingMonthStr + '-' + upcomingDayStr

    axios.get(`https://www.thesportsdb.com/api/v1/json/1/eventsday.php?d=${upcomingDateNum}`).then(response => {
        console.log('Sending requests')
        const responseArray = response.data.events;

        responseArray.forEach(oneresponse => {
            const eventName = oneresponse.strEvent;
            const sportName = oneresponse.strSport;
            const leagueName = oneresponse.strLeague;

            const eventsHTML= `<tr class="white-text one-event"><td><b>${eventName}</b></td><td><b>${leagueName}</b></td><td><b>${sportName}</b></td></tr>`
            
            upcomingFixtures = upcomingFixtures + eventsHTML;
        })
        console.log('Displaying events')
        console.log(upcomingFixtures)
        $( "#eventsView" ).append(upcomingFixtures);
        console.log('Done')
    }).catch(err => {
        console.log(err)
    })


}

Using the code above, we firstly extract the date for the next 24 hours and then we format it to make it compatible with the date requirements to include in our request after which we then send the request.

The request returns an array of events set to take place within the next 24 hours and then outputs it on the interface.

The GIF below gives an illustration of a user logging in and dashboard.html loading all events for the next 24 hours

Webp.net-gifmaker (32).gif

In the next tutorial we will add the prediction options for each sport. The prediction options will be tailored per sport as each sport has different characteristics and style of play.

Curriculum

Proof of Work Done

https://github.com/olatundeee/steempredict

Sort:  

Thank you for your contribution @gotgame.
After analyzing your tutorial we suggest the following points below:

  • The structure of your tutorial has improved a bit!

  • Nice work on the explanations of your code, although adding a bit more comments to the code can be helpful as well.

  • It would be interesting to have some gifs with the demonstration of what you have developed for this tutorial.

Thank you for your work in developing this tutorial.
Looking forward to your upcoming tutorials.

Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.

To view those questions and the relevant answers related to your post, click here.


Need help? Chat with us on Discord.

[utopian-moderator]

Thank you for your review, @portugalcoin! Keep up the good work!

Hi @gotgame!

Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your post is eligible for our upvote, thanks to our collaboration with @utopian-io!
Feel free to join our @steem-ua Discord server

Hi, @gotgame!

You just got a 0.16% upvote from SteemPlus!
To get higher upvotes, earn more SteemPlus Points (SPP). On your Steemit wallet, check your SPP balance and click on "How to earn SPP?" to find out all the ways to earn.
If you're not using SteemPlus yet, please check our last posts in here to see the many ways in which SteemPlus can improve your Steem experience on Steemit and Busy.

Hey, @gotgame!

Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!

Get higher incentives and support Utopian.io!
Simply set @utopian.pay as a 5% (or higher) payout beneficiary on your contribution post (via SteemPlus or Steeditor).

Want to chat? Join us on Discord https://discord.gg/h52nFrV.

Vote for Utopian Witness!

Congratulations @gotgame! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :

You distributed more than 40000 upvotes. Your next target is to reach 41000 upvotes.

You can view your badges on your Steem Board and compare to others on the Steem Ranking
If you no longer want to receive notifications, reply to this comment with the word STOP

To support your work, I also upvoted your post!

Vote for @Steemitboard as a witness to get one more award and increased upvotes!

Hello, as a member of @steemdunk you have received a free courtesy boost! Steemdunk is an automated curation platform that is easy to use and built for the community. Join us at https://steemdunk.xyz

Upvote this comment to support the bot and increase your future rewards!

Coin Marketplace

STEEM 0.29
TRX 0.13
JST 0.033
BTC 63175.14
ETH 3047.55
USDT 1.00
SBD 3.63