Skip to Content

Happy #APIFriday! This week, let’s start building your dream developer profile.

With so much places to write blogs, answer questions, post code, etc, how do you keep it all together? If I have reputation on StackOverflow, how do my colleagues know about it on my internal profile? How do I meld all my blog posts together so I can keep track of all my work? (Well in this case, our newest colleague DJ Adams‘s work)

So this week, let’s build up our UI5 skeleton for you profile and add in our StackOverflow badges.

The nice thing about the StackOverflow API is that is is open for us to get user information. There is strict rate limiting (ie the number of calls you can make), but if we’re just looking at you, so 1 person, we shouldn’t hit that limit. Of course this is for testing and prototyping purposes 🙂

You can find documentation about the StackOverflow API on the Stack Exchange API Documentation page. Here’s the link. The nice thing about StackOverflow being part of Stack Exchange is that a lot of your developer profiles can already by aggregated together. But our aim is to aggregate this data with the more private profiles. But check out the documentation, particularly around the Users methods as that is what we will be taking a look at. Stack Exchange does allow you to test our the APIs in their REST console, so look at Users and Badges as it will be helpful to understand the data structure later on.

Now let’s open up our development environment. I’ll be using the SAP Web IDE Full Stack.

Go ahead and create a blank project. If you need some help with this in SAP Web IDE, go to File > New > Project from Template. Select SAPUI5 Application as your template.

Finish the wizard if you are in the SAP Web IDE, and meet me when you are ready to start coding.

So we’re going to start by building the skeleton of the application. My design idea was to have a header with pertinent user information, like name and contact info, and reputation info, like badges from StackOverflow. Under our header, we can use IconTabs to separate content from different sources. I want my SAP Blogs on one page, maybe LinkedIn posts on another, and we’ll throw in some Q&A from StackOverflow for good measure. These don’t have to be your options, but this is what I’ll be implementing. Have another idea (maybe one you think is better)? Let me know! Would love to hear your opinions on this.

OK, let’s do it!

Open up for view file. Let’s add some content between the content tags for the Page. If you don’t have your page skeleton in page, make sure to do that before continuing. You won’t need to if you are using Web IDE. We’ll start by creating the header. You can use whatever combinations of controls you would like, for example an ObjectHeader or an Image and Text control. I want to use some of the newest controls from UI5, so I’m going to be using the Avatar control. The Avatar control is in the sap.f library, so to simplify, we need to add that namespace. Go ahead and add the new namespace to the view.

xmlns:f="sap.f"

Now we can use that library a little more easily. So let’s add the avatar to the view. In between the <content> tags, add an Avatar control.

<f:Avatar
	src="profile_image.png"
	displaySize="L" />

We can set the size of the Avatar using the displaySize property. I set mine to L as it is part of the header so I want it to be the largest size possible. And for the src, I’m just using a placeholder here.

Maybe we would also want to display the name, so I’m going to add a Title control below the Avatar code.

<Title	
    text="User Name" 
	level="H1"  />

The Title control accepts a level which is the HTML equivalent of a header tag. Easy enough! We’ve also got some placeholder text in here.

Now let’s create our cool badge bar where we can highlight all the things we’ve done (or for some of us, highlight that we need to play catch up….). I was using a Toolbar, but noticed there wasn’t any wrapping. As anyone implemented this? I want to know your solution. So instead I used an OverflowToolbar, because DJ is so accomplished.

Toolbar and OverflowToolbar are pretty much the same implementation wise for you, so easy enough to switch between the 2. To created an aggregated Toolbar through binding, you need to set the content property of the toolbar to an array of data. We’ll create a Badges model later which will hold our badge items. If you had a look at the documentation for StackOverflow, you would recognize the badge structure to include a Rank (Bronze, Silver, or Gold), and a Name. We’ll display this information. Set up a formatter to determine which image to show. I am going to create a list of buttons in my toolbar. They won’t have any action, but they contain the data how I want it to be displayed. So I created a Button template to use for the Toolbar content aggregation.

<OverflowToolbar 
	content="{badges>/items}" >
	<content>
		<Button 
			iconFirst="false"
			icon="{
				parts: ['badges>rank'],
				formatter: '.formatter.selectIcon' }" 
			text="{badges>name}" />
	</content>
</OverflowToolbar>

OK, so this should be enough to get us started. SAVE your changes. And then let’s get some data.

Before we go to the controller, if you are in Web IDE, we need to head to the SAP Cloud Platform first. When we call APIs or any external system in Web IDE, it is best to use Destinations in SAP Cloud Platform as it handles header creation for the API call for us, which saves us a lot of headaches.

Let’s create a destination for StackOverflow/Stack Exchange API. I know you know the drill hear, so go ahead and set it up. If you need some help, see the screenshot below.

Make sure to SAVE the destination, and then REFRESH your Web IDE.

Woot! Now let’s get access to this data source.

Open your neo-app.json file. We have to add in the reference to the StackOverflow destination that you just created. Remember how to do this? If so, go ahead If not, copy the code snippet below into the ROUTES array.  Make sure to update the NAME property if that is not what you named your destination.

,
    {
      "path": "/stackoverflow",
      "target": {
        "type": "destination",
        "name": "StackOverflow"
      },
      "description": "StackOverflow API"
    }

SAVE your changes and then you can close the nep-app file. We won’t be editing it again.

NOW we can go to the controller. Open up your controller file. Let’s set up our init function.

onInit: function() {

}

In here, we can call the Badges method of the StackOverflow APi. What do we love? AJAX! When do we want to use it? NOW! So go ahead and add an async AJAX call to the onInit function. Need some help? Keep scrolling.

$.ajax({
	type: 'GET',
	url: "/stackoverflow/2.2/users/"+userID+"/badges?order=desc&sort=rank&site=stackoverflow",
	async: true
}).done(function(results) { });

Nice!

Once we get our results, what do we want to do with them? Bind them to the view of course!

2 things to do for this: 1) Create a new JSON Model with the results and 2) Bind it to the view. Ah! Which reminds me, we need to save the context of this before we do our AJAX call. Don’t forget it!

Before the AJAX, save the state of this.

var that = this;

In the done function, implement the new JSON Model and bind it to the view.

var badges = new sap.ui.model.json.JSONModel(results);
that.getView().setModel( badges, "badges");

Cool! To test this, add in your (on anyones) UserID where the variable is set in the AJAX call. SAVE your changes. And then we are ready to run since we set up the structure in the view. But wait! I forgot we said we have a formatter. Yikes! Need to set that up.

Let’s create that file. Under the Model folder, create a new file called formatter.js. Add in the skeleton code.

sap.ui.define([
	], function () {
		"use strict";
		return {};

	}
);

Now we need to define the selectIcon function we want to use in the View. In the return array, add this function outline. We will need to accept the RANK as a parameter.

selectIcon: function(sRank) { }

In the function, we can select which Icon to use depending on the rank as well as a default. Mine looks a little something like this.

var icon;
if(sRank == "bronze"){
	icon = "resources/bronze.png";
} else if (sRank == "silver") {
	icon = "resources/silver.png";
} else if (sRank == "gold"){
	icon = "resources/gold.png";
} else {
	icon = "resources/unknown.png";
}
return icon;

You can define local resources or use icons on the web. Your choice!

SAVE your changes and then let’s head back to the Controller function.

In the controller, we need to initialize the formatter.

Add the formatter to the define array.

"profile/sap/com/communityprofile/model/formatter"

Inside the controller function, initialize the formatter.

formatter: formatter,

And SAVE your changes.

Now let’s run your app! You will see a Toolbar filled with Badges from StackOverflow.

The last piece we will do today is get some User data.

In the controller, we need to add another AJAX call to the onInit function. This time, we want the User method.

$.ajax({
	type: 'GET',
	url: "/stackoverflow/2.2/users/"+userID+"?order=desc&sort=reputation",
	async: true
}).done(function(results){});

In the done function, we need to create a new model again and bind it to the view.

var user = new sap.ui.model.json.JSONModel(results);
that.getView().setModel( user, "user");

SAVE these changes.

Back to the view! Let’s make a few edits to the Header that we constructed earlier. If you had a look at the API before hand, you know we have a display name and profile image properties we can use to fill in the avatar and title.

Let’s bind our model to these controls.

In the Avatar control, update the src to be the User profile_image. In the Title control, update the text to use the User display_name.

<f:Avatar
	src="{user>/items/0/profile_image}"
	displaySize="L" />
<Title	text="{user>/items/0/display_name}" 
	level="H1" />

SAVE your changes and re-run your app. You’ll now have the name and image of the user displayed too!

Of course you can play around with different layout settings to make it look more like what you would want, but I’m just here to get you started!

That’s all for today folks! Keep on coming back to #APIFriday as we continue to build out our dream developer profile. And share your ideas with me! Send me a tweet, comment below, share a link to your app. Let me see where your imagination is heading and let’s work to make it a reality.

Until next, have a great #APIFriday!

To report this post you need to login first.

11 Comments

You must be Logged on to comment or reply to a post.

  1. Sergio Guerrero

    nice blog Meredith. very cool that you are able to display the badges from stack overflow….

    regarding the wrapping on the toolbar… I am not sure if this is what you would want to see but.. have you used the icon tab bar control ?  it allows you to set the various icons (maybe your badges) on the toolbar area… and if you have more content than the visible space, then it adds some arrows for the user to be able to wrap…. check it out

    https://sapui5.hana.ondemand.com/#/sample/sap.m.sample.IconTabBarOverflowSelectList/preview

    hope that is what you were looking for?    happy friday and thanks again — keep up the #APIFriday blogs.

    (2) 
    1. Meredith Hassett Post author

      Hi Sergio, I will take a look at using the icon tab bar for badges. Wonder how it will look…

      What I was thinking is that if the list is longer than the page, the toolbar would wrap and we would get a 2nd layer of buttons. The overflow toolbar gives us the … at the end if the list doesn’t fit in the page width, which is a fine solution too.

      Thank you!

      (2) 
      1. Sergio Guerrero

        yes I see that…. the icon tool bar will have arrows (beginning and end) so it will let you scroll. either way, I think your approach is also a good one since … signifies there is more content… Thank you again for your post!

        (0) 
  2. Lars Breddemann

    Very nice example code!

    Wouldn’t it be great if one could do similar things with the SAP Community Platform?

    Maybe this blog post can serve as inspiration to the platform strategy.

    👍

    (0) 
  3. Former Member

    Meredith,

    Thank you for being so generous with your knowledge & experience! It helps me a lot with taking my first steps into the UI5 world, which is overwhelming coming from an ABAP background.

    Which brings me to my question: Is the sourcecode available on GitHub ? Even with your hints/tips I can’t get it to work, so I must be doing something wrong.

    Hope you can help me.

    Kind regards,

    Dirk.

     

    (0) 
    1. Meredith Hassett Post author

      Hi Dirk,

      I am not able to share my source code since I am an SAP employee. However, I will point you to our tutorial system to help learn some fundamentals of UI5 and calling APIs as well.

      If you post the error you are seeing in the Developer Tools pane (F12), the community can help you debug what is going on!

      Here’s some UI5 tutorials: https://www.sap.com/developer/groups/cp-frontend-ui5-1.html

      Here’s some API related tutorials: https://www.sap.com/developer/groups/api-ui-1.html

      Hope this helps!

      Meredith

       

      (0) 
  4. Wenbin Yin

    Hi Meredith

    Great post !

    I followed your guidence and got several questions, could you help to check if got sometimes.

    1. user>/items/0/profile_image doesn’t work (please refer to below image). I checked the API document and didn’t find where can I get the profile_image info. Could you help to explain how does this work?

    2. I’d like to fetch comments also, does below url correct?

    $.ajax({
    	type: 'GET',
    	url: "/stackoverflow/2.2/comments/"+user id+"?site=stackoverflow",
    	async: true
    }).done(function(results) {
    	var sComments = new sap.ui.model.json.JSONModel(results);
    	that.getView().setModel(sComments, "comments");
    });

    And may I use it in the view like below?

    <OverflowToolbar content = "{comments/1087366}">
    	<content>
    		<Text text = "{comments>/items/0}"></Text>
    	</content>
    </OverflowToolbar>

    Regards

    (0) 
    1. Wenbin Yin

      Hi Meredith

      solved.

      1. user JSONModel need to be created in controller.

      2. content = “{comments>/items}” and use the correct data binding path.

      Thanks & Regards

      (0) 

Leave a Reply