OnsenUI: How to Create Flickr Public Photos App in 5min
In this blog, I will walk through how to make an App that fetch photos from Flickr public photos api using Onsen UI. Plus how to use Button's spinner animation to make the App looks alive.
We will create the app below. Feel free to play with it.
1. Create the project from an Onsen minimum template
1. Go to Dashboard and click New Project
2. Choose Onsen UI Minimum Template
Name the project Flickr, and launch the IDE.
The template provides a navigator that manages two pages--page1.html and page2.html.
2. Write some codes
1. Delete page2.html
Since our app is a one page application, we do not need page2.html.
Right-click on page2.html and choose Delete.
2. Change navigator toolbar's title
Double click home_navigator.html and change title="Page 1" to title="Flickr"
3. Create a Controller for managing the feeds
Create a file called flickr.js in www folder.
function FlickrController ($scope) {
$scope.fetchPhotos = function(){
$scope.failed = false;
$scope.isFetching = true;
$.ajax({
url: "http://api.flickr.com/services/feeds/photos_public.gne?format=json",
dataType: "jsonp",
jsonpCallback: 'jsonFlickrFeed',
success: function(feeds){
$scope.$apply(function(){
$scope.feeds = feeds;
$scope.isFetching = false;
$scope.failed = false;
});
},
error: function(error){
$scope.$apply(function(){
$scope.failed = true;
$scope.isFetching = false;
});
}
});
};
}
3. Linking flickr.js with index.html
Add this line to index.html
<script src="flickr.js"></script>
4. Modify page1.html to display the feeds in FlickrController
Open page1.html and replace the centent with the following codes:
<div ng-controller="FlickrController">
<ons-list>
<ons-list-item class="center">
<ons-button type="cta" should-spin="{{isFetching}}" ng-click="fetchPhotos()">Fetch Photos</ons-button>
</ons-list-item>
<ons-list-item ng-animate="'zoom'" ng-show="failed">
Oops! looks like Flickr is down.
</ons-list-item>
<ons-list-item ng-repeat="item in feeds.items">
<img width="100%" ng-src="{{item.media.m}}">
</ons-list-item>
</ons-list>
</div>
5. How FlickrController and page1.html are connected
Onsen UI uses AngularJs under the hood. In AngularJs, we can link a controller to an element using ng-controller. The controller can provide data to DOM via scope as illustrated in the figure below:
1 We declare a controller called FlickrController by defining a function with $scope injected. We can then use the $scope to provide data to the DOM. We link the DOM to the controller via ng-controller
2 When the button is click, we tell Angular to call fetchPhotos() function of the scope.
3 We want the button to display a spinner when we are busy fetching photos from Flickr.
4 feeds.items is an array fetched from Flickr api. We use ng-repeat to display all items in that array.
5 Using ng-show we can show error message when the api call fails.
3. Wrap UP
- Onsen UI makes it easy to write rich UI application with cool animation.
- Using ng-controller, we can easily provide data to the DOM.
4. Complete source code
index.html
<!doctype html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="stylesheet" href="plugins/plugin-loader.css">
<script type="text/javascript" src="plugins/plugin-loader.js"></script>
<script src="flickr.js"></script>
<script>
angular.module('myApp', ['onsen.directives']);
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
// Now safe to use the Cordova API
}
</script>
</head>
<body>
<ons-screen page="home_navigator.html"></ons-screen>
</body>
</html>
home_navigator.html
<ons-navigator title="Flickr" page="page1.html"></ons-navigator>
flickr.js
function FlickrController ($scope) {
$scope.fetchPhotos = function(){
$scope.failed = false;
$scope.isFetching = true;
$.ajax({
url: "http://api.flickr.com/services/feeds/photos_public.gne?format=json",
dataType: "jsonp",
jsonpCallback: 'jsonFlickrFeed',
success: function(feeds){
$scope.$apply(function(){
$scope.feeds = feeds;
$scope.isFetching = false;
$scope.failed = false;
});
},
error: function(error){
$scope.$apply(function(){
$scope.failed = true;
$scope.isFetching = false;
});
}
});
};
}
page1.html
>>HTML
Oops! looks like Flickr is down.
<<HTML