Remember last time I’ve promised that I’ll tidy up our AngularJS app by creating a new service? Today in this tutorial (and the next one), I’ll show you nothing but creating a new service called
WPService, and by adding the
WPService service as a dependency for our controllers, we’ll also rewrite the code piece by piece. If you’re ready now, just open your favorite editor and dive into the code with me.
What is Angular services?
By its definition, Angular services “are substitutable objects that are wired together using dependency injection (DI). You can use services to organize and share code across your app“. Even we don’t necessarily create services for our AngularJS apps, Angular offers several useful services to us, the one we use all over this project is
$http service. You can find a complete built-in services list here.
Besides “organizing and share code across the app”, the most powerful part is that we can share data between controllers via services. For example, you might notice that we query categories from WP-API on each page, but they are the same thing all the time, do we really have to request every time the page loads? Of course not! Let me demonstrate the most important step at the beginning of this tutorial.
Hint: Before that, if you’d like to dig into the differences between these three ways to create services:
provider, there’s a very excellent article written by Tyler McGinnis, it’s a must read if you’re serious about AngularJS, I highly recommend it.
0. Getting started
As usual, please get a copy of the project files (a standard WordPress theme) from my GitHub repository. You can follow this tutorial right away with the ready made theme. I also encourage you to check out my series on building WordPress themes with AngularJS and WP REST API, I spent a lot of time on writing and improving the content. If you’re new to AngularJS, I believe it will be a good start point to you.
1. Creating a service
In this tutorial, I will create a service with
factory and name it
WPService, which will return data from WP API to our controller. Let’s start by creating a new file in the
js folder, name it
The snippet is actually very simple:
- Line 20: We register a factory function
WPServiceand we named our factory service
WPService. You can change the names – they don’t have to be the same. For example, you can absolutely change this line to:
app.factory('abcService', ['$http', defServiceFunction]);
Just remember you have to change the function name at line 1 to
- Line 1: the
WPServicefunction. Note we passed the
$httpservice as the dependency.
- Line 7-15: We add a new property to this
WPServiceobject, and it’s a
getAllCategories(). It is used to get categories from WP API (with
$http.get), and attach the results to
WPServcie.categories. (But we only call WP API when the
categoriesis empty.) So later on we can use
WPServicein our controllers and access the whole
WPServiceobject in our views (templates).
Remember to enqueue the
WPService.js in your
functions.php or the script won’t work.
Hint again: If you still feel confused why I created the
service, the short answer is,
factory is one of the ways to create and register services in AngularJS, so is
service. And please be sure to read Tyler’s article about
provider, that will be very helpful.
2. Updating the controllers
The second step is to update our controllers. We’ll update controllers that request categories for their views, so we’ll update the
In these controllers, first we need to add
WPService to the dependencies. Then we change the way we get categories from WP API (with the new function
WPService), and we attach a new
data property to
$scope, which is set to the
3. Updating the template
Because we attached the WPService to a new property (
$scope, we have to change the way we got categories in our template.
The template file we’ll update is
main.html, it’s the only template file that made use of the
categories property (came from the
$scope object). All we have to do is simply changing the
data.categories (at line 4) and our theme will work as usual… not really.
4. What have we improved exactly?
The magic can be illustrated well with a simple experiment. First please commit all changes then checkout the previous commit (where we started when this tutorial began). If you’re not familiar with how to do it, or just don’t get the point, let me save you some time by sharing my experiment with a GIF:
From the animation I was showing you that, every time a user goes from homepage to a category archive page, or switch between the categories, you can see (from the Network panel in the Chrome Developer Tools) there would be three more requests generated.
From the “Name” column you can tell the three requests are used to get all terms (categories), the current category and posts in the category. The first request (request to get all terms) is what we’ve talked about at the beginning of this tutorial – we don’t want to call the WP API every time the route changes, since they are all the same across these controllers (
Now you can switch back to the latest commit, and do the other experiment to see what exactly we’ve improved. Just open the Developer Tools from your browser, switch to the Network panel, and click on different categories to see the result.
Now you can see that every time we click on the category archive link, it only takes two more requests but not three. From the request rows you’ll find the terms (categories) request is the one we got rid of with the
WPService. Like we’ve talked about, we now share the categories object between controllers (
WPService. That’s why we don’t have to request categories every time the route (controller) changes.
It’s just the beginning
So that’s it – my quick and simple elaboration to help beginners to understand the
service and see how can we use it to improve our AngularJS WordPress theme.
As always, you can download the ready-to-use theme on my project repo on GitHub. I’ll write another post in the following days to talk about how to move large chunk of code from
WPService.js. So just stay tuned! And please feel free to leave comments or shoot me an email. Talk soon.