In the previous post, I spent some time to walk you through the basics about
services in AngularJS, including what is a service, how to create a
factory service, and what exactly can be improved with the new
WPService created by us.
So basically it’s mainly about how to share data between controllers with a service (which looks so magical especially when we change the routes). If you’re convinced by the example I just demoed, I’m glad to show you another important usage about
services, which we’ve mentioned that they are designed to organize and share code across the AngularJS app. That’s why I’m saying we can tidy up our AngularJS WordPress theme with a service.
Let’s start by taking a look at the controllers in
scripts.js – the
Paged controller, to see if there’s anything can be rewritten to be reusable, and move the reusable code into our
0. Getting Started
Everything you’ll need for this tutorial can be found at the GitHub repository, just download the theme and install it as a regular WordPress theme. It should work on any WordPress install with the WP REST API plugin activated. You can have a preview to see what we’ve accomplished so far at this page.
1. What do these two controllers share in common?
Here’s a code snippet that contains the
Have a close look. Here are things they share in common:
- They get all categories from WP API which we’ve optimized in the previous tutorial.
- They get posts from WP API.
- They change the document title.
- They attached some new properties to the
$scopebased on the feedback from WP API. Those properties are:
The anatomy helped us to figure out what can be rewritten as reusable code and should be moved to the
WPService. Let’s keep going step by step.
2. Adding the shared properties to the
It’s very clear that these four properties can be reusable:
pageTitle, we should add them to the
WPService object in our
WPService function. And it’s a good practice we give them default values (at line 5-8).
3. Creating a
getPosts function in
Paged controller, we both query posts from WP API. So the
getPosts function is a must-have property for our
WPService service / object. Let’s create it by borrowing partial code from
- From the gist above, please note at line 3 I add a parameter for this function:
page, which will be used to pass the
pageroute parameter later.
- At line 4 I add the
pageparameter to the posts endpoint.
- At line 9, we set the
page, though at homepage, it should always be 1.
- The other things to note is that I changed all
WPService, so we could share these values between controllers.
4. Updating the
Now we should use
WPService.getPosts to get posts in the
- Line 4, we remove the
$httpservice from the dependencies.
- At line 6, I used
WPService.getPosts(1)to get all posts on the first page.
5. Updating the templates
Because we move several properties from
WPService, we should update our templates to change how they access these properties.
main.html, at line 3-5 I changed
data.posts that we need to access properties in the
The other template file we need to update is
posts-nav-link.html. At line 2-4, we changed
Now the homepage should work as usual. Let’s see what we can do next.
6. Creating a private function in
WPService to update titles
services, in the mean time, we should also pay attention that not to mess up code in the
WPService. It would be meaningless if we clean up one file but move everything messy to another. (You’re allowed to do so if you’re cleaning up your living room.)
So let’s keep digging what can be improved in the
WPService.getPosts function. Yep, that’s it, these two lines looked specious to me:
WPService.pageTitle = 'Latest Posts:'; document.querySelector('title').innerHTML = 'Home | AngularJS Demo Theme';
The gist below is what I’ll do with them:
- Line 11-14: I create a function
_updateTitlethat takes two parameters:
pageTitle, so I can change these two titles. Please note the naming convention that start a function name with an underscore (_), which is used to remind us such function is a private function that we can’t access it when we’re not in the
WPServicefunction. That said, we can’t use something like
WPService._updateTitlein our controllers.
- Line 20: replace these two lines with the
7. Updating the
WPService.getPosts to work with the
The major difference between
Paged controller is that, we add an
if/else statement for the page might not exist and we can’t get any post from WP API. Let’s update our
getPosts function to include the
getPosts function is much descriptive by itself. And we can happily change our
Paged controller to:
8. Create a
getSearchResults function in
WPService for our
After seeing how powerful an AngularJS
service can be, you must be wondering: can I use it for my custom
directive? Of course you can! We can just create another function in
WPService to get search results and use it in our
searchForm directive (that we created a while back ago).
9. Creating a
_setArchivePage function in WPService
Again, we want not only the
scripts.js is tidy, but the
WPService.js should be tidy too. I felt kind of nasty that every time we get posts from WP API, we need to write these three lines again:
WPService.posts = res; WPService.currentPage = page; WPService.totalPages = headers('X-WP-TotalPages');
My solution is kicking them into another private function – I’d like to call it
At line 5-9 our new
_setArchivePage function lies there, at line 26 and 35, we change the way we update these three properties of
10. Fix the broken
After the steps above you found the
Category controller is now broken. Stay calm, we’re going to fix it right away.
To be honest the
Category controller itself is a pretty messy one. We need to fetch the category then fetch the posts in it, and we also have to take the
page parameter for pagination.
I tried my best to keep it simple, so I created a
getPostsInCategory function and it takes two parameter:
category object) and
Category controller got updated as below. Try to click on the category links now, they should work again.
It’s still not perfect but now our code gets much more organized and sharable. You can download the finished code from the GitHub repository. Let me know your thoughts about this tutorial, I try to make it simple (and even stupid) but it’s not that easy (maybe I still mixed too much stuff together).
Anyway, I value your feedback very much and I’ll always get back to each comment, email and Twitter message as soon as I can. Just get in touch!