For the last few months, I’ve been writing extensively about two related, but seemingly contradictory points: the first is that learning a JavaScript MVC framework doesn’t equal learning JavaScript deeply. The second is that AngularJS is amazing — I love it and so should you.
If you want to learn JavaScript deeply, take a course, read a book, and study the language. If you want to build something cool quickly learn Angular. But don’t skip learning the JavaScript basics.
I think learning Angular is pretty easy, but that’s because I understand JavaScript fundamentals. If you’re new to JavaScript, then this article isn’t for you. For everyone else, here is my quick guide to getting started with AngularJS and the WordPress REST API.
AngularJS consumes RESTful APIs such as the WordPress REST API. To learn Angular, you need to understand your API, be it WordPress’s or some other API. I actually got started with Angular by playing with Firebase’s API and their Angular client. Firebase is a really cool service. Once you understand Angular basics, you should read Roy Sivan’s Torque article on using Firebase in WordPress.
Angular is about more than just APIs. To get started, you should forget about APIs and start by working with your data in objects you hard code into your files. Once you understand templates, controllers, and directives, you can work in Angular’s HTTP interface and use it to connect with a remote API.
Angular uses the model view controller pattern, which makes it hard to pick a place to start explaining how Angular works. If you’re not familiar with the MVC pattern, then think about it this way:
- The view or template defines the visual representation of the data
- The controller is the intermediary, which keeps the models up-to-date using the remote API. It also updates the model based on your interactions with the view.
- The model is the current set of data, defined by the controller and displayed by the view.
To make an Angular app work, at the very minimum, you need a controller and a template. I’m going to cover templates first and then controllers. If this is new to you, you will probably need to read the section on templates, allow yourself not to understand it, read the part on controllers and then re-read the part on templates. Remember, that this stuff isn’t very linear… and we haven’t even gotten to AJAX yet.
In this article, I’m going to provide a simple, bare-bones introduction to AngularJS. It will prepare you to start diving into development using Angular with the WordPress REST API or any RESTful API.
Getting Started
Templates And Bindings
One thing I love about Angular is that the templating is simple HTML and makes use of HTML5 bindings. Some frameworks give you a totally new way of writing HTML, but not Angular. For example, if you want an HTML element in your view with class “my-element,” with Angular, you would use:
<div class="my-element"></div>
Angular keeps your view (the V in MVC) in HTML. By the way, since PHP is a tool for creating HTML, you can make those template files in PHP just like you always did. It’s not always the best way to work, but sometimes it’s needed.
Bindings connect your views to your controllers. In the view, bindings are either created with HTML5 data attributes or a template tag wrapped in double curly brackets. Here are two simple examples to illustrate a binding. The first uses an angular directive as an HTML5 data attribute to bind a field from a model to a form input:
<input type="text" ng-model="post.title" />
Notice that this form input looks like any other form input but with the extra data attribute “ng-model” which binds it to the current model’s post.title. My second example shows how we could show this same part of the model:
<div>{{post.title}}</div>
These two examples are incomplete because they are not yet identified with any controller. We must nest them inside an element bound to a controller, which is defined with the ng-controller binding.
You can put the two together like this:
<div ng-controller="postExample"> <form> <input type="text" ng-model="post.title" /> </form> <div>{{post.title}}</div> </div>
With this, once the controller is set up, you will be able to enter a value into the input and see it display magically in the container below it.
Controllers
In the MVC pattern, controllers are responsible for defining the model and providing any logic, or other functionality needed inside of the view. Right now it just handles a post title. We’re going to work with a hard-coded model, but as you can imagine, I am slowly working up to pulling in the WordPress REST API.
In the previous section, we created a very simple view, but without a controller. Now, let’s set up the most basic Angular app with a controller that can inject a model into this view so we can view and edit the “post.”
First we need a JavaScript file that instantiates our Angular app.
(function(angular) { 'use strict'; angular.module('learnAngular', []); })(window.angular);
The third line in this code assumes you have included Angular in your page. It creates an app called “learnAngular.” You can define the extra dependencies that your app needs in the empty array in that function. For example, if you load the ng-animate library on your page, it will not be available in your app unless you updated that line to:
angular.module('learnAngular', [ 'ng.animate' ] );
Right now we have an app, but we must add our controller. There are a lot of ways to handle syntax for adding controllers and other components to an app. In this article, I’m just going to use a “.” to add the controller to our app.
Here it is with the controller empty:
(function(angular) { 'use strict'; angular.module('learnAngular', []) .controller('postExample', ['$scope', function($scope) { }]); })(window.angular);
It’s important to understand that we have injected $scope into this controller, which we called ‘postExample’. The $scope variable holds the data that is available in the view. At this point in learning Angular, think of $scope as the model. Although it’s a bit of an oversimplification, it works for our purposes.
When I talked about the view I used {{post.title}}, which assumes that $scope had a property called post with a property called title. So let’s add that:
(function(angular) { 'use strict'; angular.module('learnAngular', []) .controller('postExample', ['$scope', function($scope) { $scope.post = { title: 'Enter Title' }; }]); })(window.angular);
You can now combine this with the view from the last section and see the input update the other element magically.
If you want to see this example combined in an HTML file and working, you can in this Plunker. In fact, I strongly encourage you to open it up and start experimenting on your own.
Going Further
More Bindings
Angular has a lot of default controllers. I’m not going to list them for you because Angular has great documentation. I want to show you the ng-hide directive as an introduction.
Let’s go ahead and add a submit button to our form. It could be as simple as this:
<input type="submit" value="Save">
But, let’s make it hidden until someone changes the value of post.title away from its default “Enter Title.” Update the input to this:
<input type="submit" value="Save" ng-hide="post.title == 'Enter Title'" />
This new directive ng-hide will make the input hidden unless the expression in the binding evaluates true.
By the way, hiding and showing inputs is just one example of how Angular can create really cool, constantly updating interfaces. But don’t forget that the more an interfaces updates, if not done right, the harder it is for someone using an assistive device to use it.
One of the reasons I like Angular is because the Angular ARIA automates a lot of the work of putting proper ARIA tags into your markup. Please take a look at that module and pay extra attention to what it does and doesn’t do in order to keep your app accessible.
It might seem odd at first that in my controller I used post.title instead of just title. I technically could have, but I separated the post out because scope can also contain functions. For example, if we needed more complicated logic for our ng-hide directive, we could have called a function there.
These functions can be added to $scope inside of the controller and called through bindings. A perfect example of how we would use this would be with the directive ng-submit. This directive is used to tell Angular what to do when a form is submitted.
Let’s add ng-submit to the form element, so our controller now looks like this:
<div ng-controller="postExample"> <form ng-submit="submit()"> <input type="text" ng-model="post.title" /> <input type="submit" value="Save" ng-hide="post.title == 'Enter Title'" /> </form> <div>{{post.title}}</div> </div>
In the controller, add the function submit to $scope, like this:
$scope.submit = function(){ alert( 'save'); }
This will cause an alert to fire when your form is submitted. That’s enough to understand bindings between controller and view. It also gives us the basics we need to make our model based on content pulled from the REST API. Doing so would require using Angular’s $http service, which I’m going to cover in my next article for Torque. Also, before we get into services, you should learn a very important directive: ng-repeater, which is used for looping through arrays and object.
Looping In Angular
Hopefully, you’ve been modifying the Plunker I showed you before to keep up with these changes. It should look like this now.
In the current view, there is only one post. Of course, we are likely to want to list many posts and have them each display the same way.
We do this all the time in traditional WordPress themes. We use a loop to loop through all posts in the current WP_Query object. Angular gives us a directive called ng-repeater, which allows us to loop through a collection of items in scope.
Let’s illustrate this by adding a new view and controller. To begin, let’s add a new controller called postsExample with multiple posts in $scope. Here is our new controller:
.controller('postExample', ['$scope', function($scope) { $scope.post = { title: 'Enter Title' }; }] ).controller('postsExample', ['$scope', function($scope) { $scope.posts = [ { title: 'Post One' }, { title: 'Post Two' } ]; }]);
Now that we have posts in our model, we can create a new view. In the template for this view, we use ng-repeater to create a loop. The syntax of ng-repeater is the reverse of a php foreach loop. In PHP we use:
foreach( $posts as $post )
Our Angular repeater looks like this:
<div ng-repeat="post in posts"></div>
As you can see, we take the part of the model we want to loop, in this case “posts” and give is a name, “post” we use inside the loop. Here’s the updated template:
<div ng-controller="postsExample"> <h3>Posts:</h3> <div ng-repeat="post in posts"> {{post.title}} </div> </div>
You can also check out my updated demo.
You’re Ready To Get Started
This might not seem like a lot, but it’s the fundamentals of AngularJS. In my next article, I will discuss how to use Angular’s $http component to make AJAX requests to a remote API, such as the WordPress REST API. That component works much like jQuery’s AJAX component, so if you are familiar with that, you should see if you can go ahead and start replacing your hard-coded data with data from a remote API.
Also, keep in mind that Angular is Angular. Using the WordPress REST API as its source for JSON data is a minor detail. One of the beautiful things about working with the WordPress REST API is that it opens you up to new technologies and all of the educational resources about that technology.
If you are a WordPress developer then it’s likely that you are way more used to working with jQuery then AngularJS or a similar framework. I can’t recommend this StackOverflow answer enough for those who are used to thinking the way jQuery encourages you think about the DOM versus how you need to think about it with Angular.
AngularJS is a super-popular framework and there are a lot of great resources to help you learn it out there. If you are looking for WordPress-specific Angular resources, check out Torque contributor Roy Sivan’s series on building an app with the WordPress REST and AngularJS, his Lynda course on using AngularJS with the WordPress REST API, or the fourth part of my WordPress REST API course.
At WordCamp Miami I gave two talks on using Angular with WordPress. The first was an introductory talk — the live action adaptation of this article. The second will was a more advanced talk based on my experience creating a single-page web application as a WordPress plugin admin interface in my A/B testing plugin Ingot. For that, we used AngularJS and custom WordPress REST API endpoints. You can see my slides from those posts, and a list of helpful links in this post on my site. I hope to be able to add video to that post soon.
2 Comments