(Part 3)Tutorial On SteemConnect JS Dsteem And Steem API for JavaScript pt3

in #utopian-io6 years ago

Repository

https://github.com/igormuba/steemhere

What Will I Learn?

  • Create a SteemConnect login button
  • Grab the access_token from the URL
  • Use the access_token to get user information
  • Write the username of the logged user on the browser

Requirements

Though my goal is to make the most beginner friendly tutorial possible, the following content/knowledge might be useful

  • Basic HTML and intermediate JavaScript knowledge
  • A basic understanding of the Steem blockchain
  • Knowledge of at least what is JSON and the browser console
  • WAMP server, can be downloaded clicking here
  • Knowledge on how to configure the WAMP server

I will try to briefly cover everything so even if you don't know, I try to makethis tutorial series very CTRL+C CTRL+V friendly for non programmers! But having the knowledge mentioned above can get you much further.

Difficulty

  • Intermediate

Tutorial Contents

Previously we have generated the login URL and copied from the console, now we need to add it to the HTML file.

@maargarita have contributed on the Github to make the index cleaner, fixed a few bugs and helped me finish the content of this class, so it should look like this, follow the example and remove the other script tags leaving only the SteemConnect one, like this

<!DOCTYPE html>
<html>

<head>
    <title></title>
</head>

<body>


    <script src="https://cdn.jsdelivr.net/npm/steemconnect@latest"></script>

    <script src="js/myscript.js"></script>
</body>

</html>

Another change that was made is that now the JavaScript file is named myscript.js while previously it was myapp.js
Just rename the file inside the js folder and change the file name to myscript.js and on the index HTML file change

<script src="js/myapp.js"></script>

to

<script src="js/myscript.js"></script>

This change is useful because we will have more javascript files in the future and we want to leave the name myapp.js free for future use.

Creating the Sign In button
To create the sign in button, just use an anchor tag with the href pointing to the URL your console have generated to login to the SteemConnect, it will look like

<a href="https://steemconnect.com/oauth2/authorize?client_id=steemhere&redirect_uri=http%3A%2F%2Flocalhost&scope=vote,comment">login</a>

It is the openning tag <a> with the closing tag </a> with an href inside the openning tag that looks like <a href="your link goes here">, just insert the URL grabbed form on the href and the text to click before the </a> and after the >

Now we will need to host this files on the WAMP server, else we will be redirected to the localhost (as configured in the previous tutorial) but it will give some kind of 404 because we don't have a localhost server to the browser to find the files

So, download and install the XAMP server or any server software you are used to, in my case I am using XAMP on Windows 10.
Now open the server folder, you might have set it up on installation, if not, depending on your operating system, it might be in a different folder. Find your www folder and get inside.
In my case, XAMP on Windows, it on the directory
C:\wamp64\www
Find your www folder and get inside

Copy the index and the js folder and paste them inside the www folder

Now, you must create a JSON file, simply create a file called package.json and inside it put the following code so we can decode the information we will receive from the API.

{
    "dependencies": {
        "steemconnect": "^2.0.1"
    },
    "devDependencies": {
        "http-server": "^0.11.1"
    }
}

open the browser and put on the URL bar just "localhost" or "127.0.0.1" to open the website from the local server
If you have created the login link, you will see this

Now click the button to login and get the access_token, I will teach you right after this ho to grab the access token automatically.

If all went well you were redirected to the localhost.

check the URL that is in your browser, it has a lot of characters

You will see the exact code of the access_token right there, I am not showing it in full for security reasons, this is a real access token for the steemconnect.

But our code still can't access the token. Now we will get a little tiny bit more advanced in JavaScript and grab this URL, separate the variables it has and save the access_token for later usage.

So now, head into the myscript.js that is inside the js folder. We will get our hands dirty with JavaScript.

This is the exact code to break the URL that SteemConnect sent back to us into smaller variables so that we can work with them. I thought of just removing everything else and and leaving only the access token, but thinking ahead and planning for the future classes, it will be useful to have a function to break the URL into smaller variables.

function getUrlVars() {
    var vars = {};
    var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
        vars[key] = value;
    });
    return vars;
}

The code above can be found in much more details on the html-online website, since our focus is not JavaScript, but Steem APIs, I recommend you to head over there and read what is this doing. JavaScript is very important for this classes, though I will keep posting supplementary tutorials, you can jump ahead and go there to learn the foundations before our next core API classes.

This code has set up the functions, and as I have shown on our previous supplementary content tutorial the function won't call itself.

We will create a variable and call that function to give the value of the variable.

var access_token=getUrlVars()["access_token"];

If you want to check if things are working properly, tell JavaScript to output what value is saved in the access_token variable using the console.log(); command

console.log(access_token);

If everything is fine you will get the code outputted

But there is still an issue. The variables are lost when you close the browser or change the page. If you don't save it somewhere that does not lose it the user will have to login again every time.
What we want now are Cookies

Not the ones like the image above, but browser cookies. Cookies are stored in your browser for the website and are not lost when you close or change pages. This is perfect for what we want.

As said before, this is not a JavaScript class, this is a Steem and SteemConnect API class, but I am committed on trying my best so that even a beginner can do this. This classes are a result of my frustration with not so beginner friendly documentation and lack of learning material to build Steem apps. Seriously, I couldn't find classes even on youtube, and Youtube is the greatest teacher I have ever had. So, I will use a slightly modified version of the code from the w3schools website to set and get the cookies.

function setCookie(access_token, exdays){
         var d = new Date();
        d.setTime(d.getTime() + (exdays*24*60*60*1000));
        var expires = "expires="+ d.toUTCString();
    var access_token_cookies="access_token_cookies="+access_token+";" + expires + ";path=/";
    document.cookie=access_token_cookies;
}

The function above will receive the value of the token and save it to a cookie named "access_token_cookies"
The function from the w3schools is very complete, and better than the one I have previously written myself, because it allows us to, in the future, save and retrieve multiple cookies, in the version I have made without future proof thinking we could only store one.
To practice, after setting this function and reading their tutorial, try to spot what changes have I have to personalize our function to work with our acces_token

So, please, read the tutorial on
https://www.w3schools.com/js/js_cookies.asp
To understand what are we doing. They explain in details and very well and focusing on what is the JavaScript doing.

Now, we need to call the function to, in fact, set the delicious cookie.
Simply add below all of previous code

setCookie(access_token, 7);

The function received the code and saved it in the cookies as access_token_cookies

Now, we need to debug to see if the cookie is set, but for this we need to retrieve the cookie.
Based on the JavaScript tutorial from w3schools, simply use the code for the following function, diferently from the other one

function getCookie(cookie) {
    var name = cookie + "=";
    var decodedCookie = decodeURIComponent(document.cookie);
    var ca = decodedCookie.split(';');
    for(var i = 0; i <ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0) == ' ') {
            c = c.substring(1);
        }
        if (c.indexOf(name) == 0) {
            return c.substring(name.length, c.length);
        }
    }
    return "";
}

Again for practice, I recommend you reading their tutorial and trying to spot what changes have I made to personalize and make this function work with our access_token.

Now we must debug to check if the cookie was successfully saved and if we can successfully retrieve it.

To do this, first remove the previous console.log() and then

console.log(getCookie("access_token_cookies"));

I suppose you must have understood that we have called the function asked for a cookie named access_token_cookies

The output should be exactly the same on the previous console.log() we have done

Now we are really going to use the SteemConnect API to get real data from the blockchain!
This is the fun part.
We have the login button, we have the access token, now we must work with it.
Delete the console.log() to make the console output clean.

Make sure that the piece of code that sets the API is in the very very end of the code.
It all will look like this

function getUrlVars() {
    var vars = {};
    var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
        vars[key] = value;
    });
    return vars;
}

function setCookie(access_token, 7){
    var access_token_cookies="access_token_cookies="+access_token+";path=/";
    document.cookie=access_token_cookies;
    console.log("cookie criado "+access_token_cookies);
}

function getCookie(cookie) {
    var name = cookie + "=";
    var decodedCookie = decodeURIComponent(document.cookie);
    var ca = decodedCookie.split(';');
    for(var i = 0; i <ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0) == ' ') {
            c = c.substring(1);
        }
        if (c.indexOf(name) == 0) {
            return c.substring(name.length, c.length);
        }
    }
    return "";
}

var access_token=getUrlVars()["access_token"];
setCookie(access_token, 7);

var api = sc2.Initialize({
    app: 'steemhere',
    callbackURL: 'http://localhost',
    accessToken: access_token,
    scope: ['vote', 'comment']
});

The definition of getUrlVars(), setCookie(access_token) and getCookie(cookie) must come at the very first becaus eJavaScript reads one line at a time, if we call them and they are not defined we will have weird errors.
Then make sure that we get the token and set it on the cookies before we initiliaze the API.

Now, after you have set the cookie, I recommend you to change the token variable to get the value from the URL to get the value saved on the cookies, so in the case there is no token in the URL the browser will search the cookies.
Also, we need to make sure to NOT SET THE COOKIES TO NULL, seriously, I spent 30 minutes and almost got crazy because the cookie was going back to null, but I will teach you how to not commit this mistake as such small things can make you lose motivation. Here we go

You see, we are blindlessly setting the cookie, so if we just go to localhost without the token in the URL the cookie would be set to undefined.

so you need to wrap it with an if checker to only set it if the url token is not null, it will look like this

if (access_token!="" && access_token!=null){
setCookie(access_token, 7);
}

I have just saved you 30 minutes of frustation haha

So if there is a token in the url, it will go to the cookies, if it is not, for now we will suppose it is in the cookies, so create a new variable and check if it really retrieved the token stored and not in the url

var access_token_in_cookies = getCookie("access_token_cookies");
console.log("fromcookies is" + access_token_in_cookies);

login again to make sure it saved the cookie and now delete everything on the URL bar on the browser and type just localhost and access it, if everything was done right, you should see this

There is no access_token on the url, but we have successfully saved it on the cookies! I don't know if this makes as you excited as I am, but I was really happy for this to work.
On chrome on the tab "Application" you can also see the cookie itself, AND IT IS NOT NULL!!! Yey!

Now, the last step, if to get the username and profile picture from the blockchain of Steem and write in the broser, we will need to go back to HTML for a brief moment, and here the supplementary class I have posted yesterday will be very useful for beginners.

On the HTML create a h1 tag and an image tag, as follow

<h1 id="username"></h1>
<img src="" id="picture">

We are done with HTML haha
Simple, all the work now will be back on the JavaScript file

On the myscript.js add at the very end

api.me(function(err, res) {
    console.log(err, res);
});

And make sure that the code above is below the code below (mind twist)

var api = sc2.Initialize({
    app: 'steemhere',
    callbackURL: 'http://localhost',
    accessToken: access_token,
    scope: ['vote', 'comment']
});

And also, in this last chunk of code, change the accessToken: access_token, to accessToken: access_token_in_cookies,, so we are consulting the Steem API WITH THE COOKIE ACCESS TOKEN.

To test if you did it right, just save it all and go to localhost, without any tokens or anything on the URL, supposedly it should fetch the token from the cookies and you shall see your own account's information

Now things are gonna get so, SO COOL!!
Look, in a few lines of code we can wrap all this work up and see the results. Stick with me here.

in the api.me(function(err, res) after the console.log(err, res); you need to add an if, if this does not output an error we are going to put the username and profile picture in the page, finally!

The code will be as follows

api.me(function(err, res) {
    console.log(err, res);
    if (!err) {
          document.getElementById("username").innerHTML = res.user;
          document.getElementById("picture").src = "https://steemitimages.com/u/"+res.user+"/avatar";
        }
});

What we are doing above is:
we use DOM manipulation to get the h1 element and set the HTML content inside the tags to res.user.
if you want to understand why res.user you can search about JSON online but briefly, the data from the user is temporarily stored in the res, and inside the res is the user, check the image for a better understanding

basically the object is the res and user is it's direct children.

Save everything and reload the page AAAAAND

CONGRATULATIONS!
You have succesfully logged one user in, stored it's SteemConnect access token, used this token to get his information directly from the blockchain and filled the page with his information.

I can't wait to show you more cool things you can do in the next tutorial!

Curriculum

Previous classes, feel free to read them all or skip the ones you already know about the content

Proof of Work Done

Final index.html file on github
Final myscript.js on github
Final package.json on github

Beneficiaries of this post

From now on, I am using SteemPlus to give 50% of the rewards to a few beneficiaries

Each of the beneficiaries will receive a percentage, 50% of the post rewards will be shared among chosen projects/users, 5% of this automatically goes to SteemPlus.

  • @steem-plus:5%
  • @utopian.pay20%
  • @maargarita25%
  • Special Thanks

    I must leave here a special thanks to my good friend @maargarita, she have helped to solve a small problem I was facing and without her this tutorial would have been delayed until I could find a solution. Thank you very very much.
    She is not very active on the Steem community, but I am trying to bring her back, she is very smart and her knowledge can be great and very useful to all Steem, so I highly recommend following her as an incentive and to stay tuned to her new content.

    This class took 7 hours to make

    From the time I clicked to create a new post, until right now, when I am almost clicking "post", it took me 7 hours to write the tutorial, fix bugs, write simpler code and compare my solutions with other online to present you with the best and most easy to understand content possible. Even when I already had the code done, putting it into a tutorial, going back and redoing step by step is a path full of challenges and bugs, I tried my best to find and fix any bug possible and present a final and complete solution on the tutorial.
    Please, consider upvoting, resteeming and voting for me for witness
    https://steemconnect.com/sign/account-witness-vote?witness=igormuba&approve=1

    Hey, I am Witness, did you know?

    To vote for me, go to https://steemit.com/~witnesses

    (note, it is /~witnesses, not /witness)
    Scroll all the way down to "If you would like to vote for a witness outside of the top 100, enter the account name below to cast a vote."

    type igormuba and click vote

    Sort:  

    I thank you for your contribution. Here are my thoughts. Note that, my thoughts are my personal ideas on your post and they are not directly related to the review and scoring unlike the answers I gave in the questionnaire;

    • Structure

      • It's hard to figure out which part does what. So, I advise you using headers to categorize the post.

      • I advise you to consider using paragraphs more. Separating each sentence with a blank line makes it harder to read and comprehend.

      • The images split the post too much. I don't know what to advise; but if possible, shrinking them would make a difference. You don't have to change anything, but it just caught my eye.


    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? Write a ticket on https://support.utopian.io/.
    Chat with us on Discord.
    [utopian-moderator]

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

    Hi, thank you very very much for sharing your personal thought, as my goal is to make the series as beginner friendly and even CTRL+C CTRL+V friendly as possible I can see how the structure is important for people to spot exactly what part interest them the most.
    Thank you for the useful comment, will improve on the next version

    Posted using Partiko Android

    Congratulations! This post has been upvoted from the communal account, @minnowsupport, by igormuba from the Minnow Support Project. It's a witness project run by aggroed, ausbitbank, teamsteem, someguy123, neoxian, followbtcnews, and netuoso. The goal is to help Steemit grow by supporting Minnows. Please find us at the Peace, Abundance, and Liberty Network (PALnet) Discord Channel. It's a completely public and open space to all members of the Steemit community who voluntarily choose to be there.

    If you would like to delegate to the Minnow Support Project you can do so by clicking on the following links: 50SP, 100SP, 250SP, 500SP, 1000SP, 5000SP.
    Be sure to leave at least 50SP undelegated on your account.

    From now on, I am using SteemPlus to give 50% of the rewards to a few beneficiaries

    I suggest you build up your account more before you give such generous rewards to beneficiaries!

    Some of those have helped me a lot to get where I am, I have decided on 50% as fair not only because of their support, but also because either

    1. the rewards are low, so it does not matter to make a little less money

    2. the rewards are high, so it does not matter maaking 50% less and considering it an investment

    but I am open to try new things, will leave the rewards at 50-50 for some days and weeks and see how it goes.

    thank you for making me think more about that

    Hi @igormuba!

    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

    Hey, @igormuba!

    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!

    sc2 is not defined

    Coin Marketplace

    STEEM 0.20
    TRX 0.13
    JST 0.030
    BTC 66408.50
    ETH 3486.20
    USDT 1.00
    SBD 2.70