Creating a news app using UI5
Topics covered
In this blog we're going to create a super simple UI5 application that uses the news api to pull in our data and then display that data using the generic tile control.
News API
News API is simply an easy to use API for developers to request news data from all over the world and with a number of filters built in such as country and category.
Head on over to https://newsapi.org/ and sign-up for an account, this takes almost no time as you'll need the API key.
Getting started
Create a new UI5 application through your chosen method, I personally use ExpressUI5 to make applications like this. Disclaimer I made this small node package and have a blog on how to use it here. But if you're new to UI5 I'd suggest the use of WebIDE as it's super easy for beginners and they have a template for simple applications just like this.
News.js
I actually decided to create a small file called news.js to handle my get request to the news API, this isn't required but I'd recommend getting used to the practice of splitting up your code into reusable files. Here is an example of my project structure:
Inside of news.js I have the following code:
sap.ui.define([], function () {
"use strict";
return {
getNews: function()
{
const url = 'https://newsapi.org/v2/top-headlines?country=GB&category=business&' + 'apiKey=YOURAPIKEY';
const req = new Request(url);
return fetch(req).then(response => response.json()).then(json => json.articles)
}
};
});
So news.js has a single function which simply hooks into the news API and returns to us articles with the country code of GB and category of business. Make sure to replace 'YOURAPIKEY' with your actual API key provided from the newsapi.org website.
The Controller
Inside of my UI5 controller
sap.ui.define([
"nathan/hand/news/api/controller/baseController",
"sap/ui/model/json/JSONModel",
"nathan/hand/news/api/util/news"
], function(baseController, JSONModel, news) {
"use strict";
return baseController.extend("nathan.hand.news.api.controller.mainView", {
onInit: function() {
news.getNews().then(articles => this.setArticlesModel(articles));
},
setArticlesModel: function(articles)
{
var articlesJson = new JSONModel(articles);
this.getView().setModel(articlesJson, "articles");
},
});
});
We import our news.js file at the top of the UI5 controller and then simply call our getNews function. Then on return of our promise call our setArticlesModel function which will create our UI5 model that we need to bind out data to the generic tile.
The View
Inside of our view
<mvc:View controllerName="nathan.hand.news.api.controller.mainView" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:mvc="sap.ui.core.mvc"
displayBlock="true" xmlns="sap.m">
<App>
<pages>
<Page title="{i18n>title}">
<content>
<GenericTile
backgroundImage="{articles>/0/urlToImage}"
frameType="TwoByOne" press="onArticlePress">
<TileContent footer="{articles>/0/publishedAt}">
<NewsContent
contentText="{articles>/0/title}"
subheader="{articles>/0/description}" />
</TileContent>
</GenericTile>
</content>
</Page>
</pages>
</App>
</mvc:View>
Above is our view, this isn't the finished product because as some of you might have noticed we're calling the first element in our model directly in the view binding. I just wanted to see our tile with our data as expected in our running app which given the above should look something like this:
Don't worry if your background image isn't filled in/ is blank as not all of the news stories coming from the API will have that and this is just an example application.
How to show all of our articles
One thing that I learned a while ago using UI5 is that not all standard controls have aggregations to bind multiple items, I could have used a different control for this blog post but I wanted to show off this little trick that I learned a while ago which is to use the Grid control.
So importing Layout to our view and making a few changes to our view will result in something like this:
<mvc:View controllerName="nathan.hand.news.api.controller.mainView" xmlns:l="sap.ui.layout" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:mvc="sap.ui.core.mvc"
displayBlock="true" xmlns="sap.m">
<App>
<pages>
<Page title="{i18n>title}">
<content>
<l:Grid
content="{articles>/}"
class="sapUiSmallMarginTop"
hSpacing="2"
defaultSpan="L4 M6 S12">
<GenericTile
backgroundImage="{articles>urlToImage}"
frameType="TwoByOne" press="onArticlePress">
<TileContent footer="{articles>publishedAt}">
<NewsContent
contentText="{articles>title}"
subheader="{articles>description}" />
</TileContent>
</GenericTile>
</l:Grid>
</content>
</Page>
</pages>
</App>
</mvc:View>
Inside of the Grid control we can specify our content aggregation and bind that to our JSON model which means our generic tile will be repeated with each element in our JSON model and we can drop the '0' found in our previous example.
The grid is especially useful here because we can specify our defaultSpan which means that our tiles will also now be responsive and actually looks like this:
Conclusion
We've managed to create a super simple news application using UI5 and the newsapi.org API. There's lots to clean up here such as implementing our press event and formatting the article date but I hope this has been a useful base on getting up and running using an external API and UI5 together.
Questions? Comments and general feedback? Leave them down below or reach out to me on Twitter.
···