Tutorial: Creating an AngularJS app with node.js and Heroku Part II

February 24, 2013 Appirio

by Bryan Leboff

So now that we have our environment set up from Part I of this tutorial, it’s time to start coding the AngularJS app.  The app will simply show a set of photos from Instagram based on your current location.  This will allow us to touch on some key elements in AngularJS such as controllers, views, routes,  services, and directives

The first thing we’ll want to do is remove the stuff we don’t need from angular-seed, and repurpose the stuff we do need. I suggest reading through the getting started guide if you are unfamiliar with AngularJS as we will be touching on some of the concepts in there.

Some Clean-up tasks

The angular-seed app contains two controllers (MyCtrl1 and MyCtrl2) for this app we will only need one so let’s delete the MyCtrl2 route from app.js, the controller from controllers.js and the view2.html partial they reference.

Now that MyCtrl2 is gone, let’s rename MyCtrl1 to something more meaningful. In this case we’ll call it HomeController as it will be our home page. Let’s rename partial1.html to home.html and we can remove the navigation and version lines from index.html because we will not need those either.

Here is what your app.js, controllers.js and index.html should look like now.

Prerequesites

We are going to making use of some jQuery and javascript libraries in our app.  I will list them here, just add them to you /lib and index.html file.
jQuery: you know this one.

Instagram Authentication

NOTE: At this point it appears Instagram doesn’t like having a hash (#) in the redirect_uri so we are going to use html 5 mode which will allow us to use Angular without the hash urls in web browsers with HTML5.  This means the app will not work in browsers that do not support HTML5. (I guess with the location stuff this was true anyway)

This requires adding this line to app.js (to configure HTML5 mode):
And changing web.js to look like this (to serve index.html when not finding a route):
In order to use our app with Instagram we will need to authenticate the user first because the search method requires authentication. This is a fairly straight forward process that involves sending the user to Instagram to authenticate and registering a callback url that Instagram will send them to after registration.  So after registering for access to the API at Instagram  for our dev environment set your callback url as “http://localhost:5000/instagram” (we will change this later).

We will be using oAuth2’s client side authentication flow to authenticate our users. So all we need to do is send them to this URL
https://instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=REDIRECT-URI&response_type=token

And when they authorize the application, get the access token from our callback.

So first we create the InstagramAuthController. This will grab the auth token from the Instagram callback and it will contain this logic for getting and storing the user’s authentication token.  After we have all that data, we redirect the newly authenticated user to home.

For the token storing we will create an AngularJS service called InstagramToken. AngularJS comes with a service for accessing and manipulating cookies, $cookies.  This will take care of storing and retrieving the token throughout the app.  Also while we’re in services, we’ll add the value for our Instagram search URL

Then we add /instagram route to app.js:
And finally create the authorize link (I do it directly in HTML, you can write a filter to create it for you from your client id and redirect uri if you prefer)

Add some Location

The next thing we’ll want to do is add some logic to our controller to get the user’s current location.  This is actually very simple as we just need to access the location object in HTML5 supported browsers from our home controller.  Also, we will only run this if the user is already authenticated to Instagram ($scope.token is truthy).

Grab the Images

Now that we have all the data we need to tell Instagram what we want, lets go out and run a search request for our location.  So our position acquired callback will make the call to Instagram to search for available images.
Now we can do a get call with the $http service, and populate our $scope.images with the results.  Because of the cross-site nature of request we need to use the jsonp method in $http.
Add these lines to your home controller

Our first Directive!

Each image in our app is going to be a directive.  Directives are one of the coolest parts of AngularJS and is a way to add new functionality to your HTML pages including DOM transformations. This allows us to keep HTML and controllers simple but provide very cool features.
What our directive will do is show a larger version and additional information in a modal dialog after clicking the image.Now our html can be very condensed (4 lines!) but provide a lot of functionality.

So here is our directive (instagramImage): Let’s talk about some of the parts

Template

The template is the html that will be rendered in place of the html tag on our page.  For example our directive is called ‘instagramImage’ so if I have element tags on our page these will contain the instagramImage template.

Restrict

The restrict parameter allows us to restrict the directive to certain declaration types.  These can be an element () attribute (

) class (

) or comment ().  For ours we will use the element type.

Scope

Scope allows us to create (or not create) a scope for each time our directive gets declared.  This can also let us bind to variables outside of our newly created scope (we use ‘image’: ‘=’ here to bind to the image variable which we get back from Instagram)

Link

Our link function will contain our javascript (read jQuery) magic.  So here we hide the high res versions of our images, and only show them when the user clicks an image, and hide them when they click again.
Link is where the DOM magic happens and is a result of the AngularJS compile process.  You can read more about that and all the attributes discussed (and plenty of additional ones) here

So let’s add the image directive to our home.html that now looks like this:

Some of the features present here are the ng-show directive which will hide the authentication link if our token is already populated, and the ng-repeat directive which will repeat an element over a list.  In our case each image in images.

Now to make this all look good, we’ll need to add these lines to our app.css file. This includes the modal dialog box and the overlay text stuff.

Deploy!

Looks like we’ve got a pretty cool working app at this point.  Time for the best part, deploying! Heroku makes this very easy as we saw in the last tutorial.
One thing we have to change is our authentication url and callback from the dev version.

So go back to Instagram and change the website and oauth redirect_uri to your Heroku  application URL.

Now commit all your changes and  run ‘git push heroku master’ (remember that one?) and you’re all set!  At this point you should have your first full-fledged AngularJS up and running on Heroku! Congrats!

If you want to check out the full source for this app it is available here for your forking/referencing pleasure.  If you have any questions or certain topics that need expanding or something I forgot or something feel free to comment and I’ll get to them as soon as I can.  Oh and you can check out the app in action here.  Its kinda cool!

 

Previous Article
Who’s Your Daddy?
Who’s Your Daddy?

by Andres Gluecksmann (@aglue) Since the Spring ‘10 release, Salesforce opened up the possibility of creati...

Next Article
Best Practices for Apex Callouts, Part 2
Best Practices for Apex Callouts, Part 2

Earlier we posted some initial considerations in designing and implementing Webservice callouts from SFDC. ...