(Part 8) Steem JavaScript API Tutorial - User Page, Reputation and User Posts pt8
Repository
https://github.com/igormuba/Steem-Feed-Example-/tree/AuthorPage
What Will I Learn?
- Create a new JavaScript reactive page (no need to reload)
- Load the user profile
- Calculate the user reputation
- Append child divs inside the shadow element
Requirements
- Internet connection
- Code editor
- Browser
- Reading the previous classes on making a Steem Feed is recommended but not necessary
Difficulty
- Advanced
Tutorial Contents
For the first time I think it is time to classify my tutorial as "advanced", I will try to cover everything is the most beginner friendly way I can, but building reactive pages without a reactive library (like react JS) can become messy, but I think it is a important path to take so you can have a true understanding on how the reactive page works without having to reload anything, users hate reloading pages
Our new JS file
On a reactive page the JavaScript create the HTML page, so everything is dinamically displayed or hidden as the user interacts with the application without having to reload anything.
So, to create the profile page, instead of creating a profile.html like we used to do for other pages, we will create a profile.js instead, because this is the Javascript that will generate the HTML page.
So, inside the JS directory of our project, create a file profile.js
And do not forget to import the new JavaScript inside our only HTML page, the index.html
<script src="js/profile.js"></script>
<script src="js/myscript.js"></script>
Small changes on the myscript.js
Think for a moment about what do we need to do to send the author information from the index page to the profile page. What do you think?
We need to pass the author name, right?
So, we could do this using global variables, but it is better to avoid those, we could also use the cookies, but that is unnecessary.
The solution I have applied is to call from the myscript.js a function from the profile.js, you are free and I incentivize you to try other solutions, maybe using the cookies, so you get hands on practice :)
So, I am gonna put an anchor tag around the author name from the post, and this anchor tag is gonna call a function that is to be defined inside the profile.js
<a href="javascript:;" onclick="loadProfile('`+result[i].author+`')">by: @`+result[i].author+`</a>
So, the h2 with the author name looks like this
<h2 class="post-author"><em><a href="javascript:;" onclick="loadProfile('`+result[i].author+`')">by: @`+result[i].author+`</a></em></h2>
The href="javascript:;" onclick="loadprofile"
means that we want this to be a link that actually calls a JavaScript function instead of a new page, and as an argument for that function we pass the author name.
If you didn't follow the past 2 tutorials I highly recommend you to do so to understand what are we doing, the list of all the classes are on the bottom of this post.
The loadProfile
function from profile.js
On the profile.js we already have an idea of what argument will it receive, so we can already define
loadProfile(author){
}
As I have said, we are going to use the same page, so it is better to clean everything before proceeding, right?
on the first line of the function above, call a function that we will define later called clearPosts()
to clear all the divs from the page so we can change their content.
loadProfile(author){
clearPosts();
}
Cleaning the posts
Now, to clean the posts it is relatively easy, just do
function clearPosts(){
for (let i = 1; i<=3;i++){
document.getElementById(i).innerHTML="";
}
}
So it will iterate through every div and clean the content.
Getting the author data
We have used this function in previous classes but for other purposes, here we will use this to get the user reputation.
Inside the loadProfile
do
steem.api.getAccounts([author], function(err, result) {
console.log(err, result);
}
This will load all the information from the author account and print on the console so we can know what do we want
In this case, we want result[0].name
and result[0].reputation
We will fill the first div with this information so it looks dettached from the posts we will put below, let us fill the sahdow element with the information
But you may notice that this gets the raw reputation from the user, we want to show the reputation level, which is the number we are used to see on Steemit and other interfaces
You can read more about the Steem reputation at
https://www.steem.center/index.php?title=Reputation_System
Sadly, on that post they teach how to calculate the reputation using pure Ruby
But I have found a very interesting post by @pilcrow on how to calculate it using JavaScript!
Check his post here
https://steemit.com/steemdev/@pilcrow/calculating-a-user-s-steemit-reputation-score-in-javascript-bonus-content-an-angular-pipe-that-does-it-for-you
The function he uses is
function simplifyReputation(raw) {
const isNegative = (raw < 0);
let reputation = Math.log10(Math.abs(raw));
reputation = Math.max(reputation - 9, 0);
reputation *= isNegative ? -9 : 9;
reputation += 25;
return Math.floor(reputation);
}
And this is the one we are going to use to translate the raw reputation into the reputation level
document.getElementById(1).innerHTML=`
<hr class="horizontal-ruler">
<h1>@`+result[0].name+`</h1>
<p>Reputation Level: `+simplifyReputation(result[0].reputation)+`</p>
<hr class="horizontal-ruler">
`;
The above reactive element manipulation is very similar to the one we did to load the feed posts
And this is the result we get
Getting the posts from the user
The loadProfile
function is the main one, so we will call the function that fills the posts inside this one
function loadProfile(author){
clearPosts();
steem.api.getAccounts([author], function(err, result) {
console.log(err, result);
document.getElementById(1).innerHTML=`
<hr class="horizontal-ruler">
<h1>@`+result[0].name+`</h1>
<p>Reputation Level: `+simplifyReputation(result[0].reputation)+`</p>
<hr class="horizontal-ruler">
`;
});
getUserFeed(author); //we pass the author so it knows it since we have cleaned the divs
}
Now we must define the getUserFeed
and we know it will receive the name of the user.
The way we will do it is very similar to how we got the posts from the feed of the user, but instead of steem.api.getDiscussionsByFeed
we will use steem.api.getDiscussionsByAuthorBeforeDate
And we this time create new divs and insert them inside the h2 div!
so, outside of the function, we will create a variable to host the posts from the user
let userPosts;
And inside the function we call the Steem function
steem.api.getDiscussionsByAuthorBeforeDate
According to the Steem JS documentation this function needs the following arguments
You can read more about the documentation at
https://github.com/steemit/steem-js/tree/master/doc
So we will pass
(user, "", '2019-05-01T00:00:00', 4, function (err, result)
So far it looks like
steem.api.getDiscussionsByAuthorBeforeDate(user, "", '2019-05-01T00:00:00', 4, function (err, result) {
console.log(err, result);
userPosts=result; //this stores the posts from the author
}
Now, we copy the technique we have used to fill in the feed but we give it some tweaks, I will first show how it looks then explain what is changed and why
let userPosts;
function getUserFeed(user){
steem.api.getDiscussionsByAuthorBeforeDate(user, "", '2019-05-01T00:00:00', 4, function (err, result) {
console.log(err, result);
userPosts=result;
for (let i=0; i<3; i++) {
let iToString = (i+1).toString();
let converter = new showdown.Converter()
let text = result[i].body
let html = converter.makeHtml(text);
// until now nothing changed from the feed
let newDiv = document.createElement("div"); //created a new div
newDiv.innerHTML = `
<hr class="horizontal-ruler">
<h1>`+result[i].title+`</h1>
<h2 class="post-author"><em><a href="javascript:;" onclick="loadProfile('`+result[i].author+`')">by: @`+result[i].author+`</a></em></h2>
<hr class="horizontal-ruler">
<p>`+html+`</p>
<hr class="horizontal-ruler">
`; //sets the contents of the div
document.getElementById(2).appendChild(newDiv); //adds the created div inside the div 2!
}
});
}
We won't use the div 3, so,above we are doing the same as the feed, but we are getting the posts from the user, not from his feed, and iterating through them all and adding them inside the div 2, instead of replacing divs by them!
the let newDiv = document.createElement("div")
created a logical div but does not put it anywhere
The newDiv.innerHTML =
tells what is the content from the div, it is the exact same as from the feed as the format is the same
Now the big change is document.getElementById(2).appendChild(newDiv);
, instead of replacing the HTML content from the div it adds content, so we can append the posts from the user in here using this.
How it looks like
In the end it will look very much like a real Steem interface, we have in this project the feed and when we click on the author we load his posts
Curriculum
Include a list of related tutorials you have already shared on Utopian that make up a Course Curriculum, if applicable.
- (Part 8) Steem JavaScript API Tutorial - Creating Pages, Scrolling The Feed Further pt8
- (Part 7) Steem JavaScript API Tutorial - Fetch And Display A Real Feed pt7
- (Part 6) SteemConnect Web API Tutorial - Create A Steem App To Convert SBD To Steem pt6
- (Part 5)Tutorial On Steem/SteemConnect JS Retrieve And Comment The Last Post @steemconnect pt5
- (Part 4)Tutorial On SteemConnect JS Submit A New Post Using @steemconnect pt4
- (Part 3)Tutorial On SteemConnect JS Dsteem And Steem API for JavaScript pt3
- (Part 2)Tutorial On SteemConnect JS Dsteem And Steem API for JavaScript pt2
- Tutorial On SteemConnect JS Dsteem And Steem API for JavaScript pt1
I AM A STEEM WITNESS
To vote for me, simply use the SteemConnect link below
https://steemconnect.com/sign/account-witness-vote?witness=igormuba&approve=1
or 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
Thank you for your contribution @igormuba.
After analyzing your tutorial we suggest the following points listed below:
We suggest that this tutorial has the difficulty level as basic. The features that you explain in your tutorial are not complex to implement.
Put more comments in the code sections. Comments are very important in the code and help less experienced users understand what they are developing.
Good work on the development of this tutorial, we hope for more 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? Write a ticket on https://support.utopian.io/.
Chat with us on Discord.
[utopian-moderator]
Thank you for your review, @portugalcoin! Keep up the good work!
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
Very useful! Thank you so much !
Posted using Partiko Android
Hi, @igormuba!
You just got a 0.38% 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, @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!