Improving Your AngularJS WordPress Theme With A Service

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: factoryservice and 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 WPService.js, and write some JavaScript into it:

The snippet is actually very simple:

  • Line 20: We register a factory function WPService and 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 defServiceFunction, too.

  • Line 1: the WPService function. Note we passed the $http service as the dependency.
  • Line 3-5: We created an object called WPService, and we return the object at line 17. So you get the idea – the WPService is just simply a JavaScript object!
  • Line 7-15: We add a new property to this WPService object, and it’s a function called 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 categories is empty.) So later on we can use WPService in our controllers and access the whole WPService object 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 WPService with factory not 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 factory, service and 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 Main, Category and Paged controller.

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 getAllCategories()from WPService), and we attach a new data property to $scope, which is set to the WPService object.

3. Updating the template

Because we attached the WPService to a new property (data) of $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 categories to 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:

Experiment 1: 3 more requests when clicking on the category archive page

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 (Main, Category and Paged).

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.

Experiment 2: 2 more requests when clicking on the category archive page

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 (Main, Category and Paged) with 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 scripts.js to WPService.js. So just stay tuned! And please feel free to leave comments or shoot me an email. Talk soon.

14 responses

  1. gaggo Avatar

    I just love it! A little thing that got me confused in the beginning was that you call your factory a service, but, after reading through the amazing tutorial by Tyler McGinnis, I see much clearer now, the Factory is returning a service.

    My my, the terminology of angular really can be quite intimidating to beginners, what a luck we have you! 😉

    1. Yoren Chang Avatar
      Yoren Chang

      Hey Gaggo, Thanks for your kind words and, you’re right about the AngularJS terminology. I hope that could be improved when the 2.0 comes out this summer.

      And thanks for your reminding, I rewrote the post a bit to change some wording, hope it can help the future reader better.

  2. Carbine Gammax Avatar
    Carbine Gammax

    Hi. Tried you tutorial and it works. The challenge i’m having, is how to refactor the service such that i can do this instead:

    $scope.data = WPService.getAllCategories

    I tried adding the return data inside the getAllCategories function and still no luck. Any insight on how to do this?

    Thanks

    1. Yoren Chang Avatar
      Yoren Chang

      Hey Carbine, this is a more advanced topic actually, it relates to a concept in Angular called “promises”. But it’s also quite easy to understand, I found a very useful tutorial for you: http://markdalgleish.com/2013/06/using-promises-in-angularjs-views/

      P.S. Please ignore the last paragraph in Mark’s post, it didn’t work that way since Angular 1.2+.

    2. I came across the same problem. Good thing I read your next post. https://1fix.io/blog/2015/06/13/tidyup-angularjs-wordpress-service/

      Thanks!

      1. Yoren Chang Avatar
        Yoren Chang

        Cool. Glad it helped!

  3. […] 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. […]

  4. Carbine Gammax Avatar
    Carbine Gammax

    Thanks for the article. Exactly what i was looking for.

    1. Yoren Chang Avatar
      Yoren Chang

      Hey Carbine, glad I can help!

  5. Since the start of the posts I was waiting for services.
    Many thanks for the awesome tutorials. they are very clear and direct to the point.

    1. Yoren Chang Avatar
      Yoren Chang

      Hi Fernando, Thanks for the kind words. Really appreciate it!

  6. I am vary thankful to you for such a great knowledge, it was vary helpful for me to learn more about angular JS.

    1. Yoren Chang Avatar
      Yoren Chang

      Hey Tracey! You’re most welcome! Thanks for letting me know.

  7. Nice post this one is about the angularjs wordpress themes, thanks for sharing this valuable and amazing information with us.

Leave a Reply

Your email address will not be published. Required fields are marked *