When Page Not Found In Your AngularJS WordPress Theme

It’s good to see you in the latest post of my Building themes with AngularJS and JSON REST API series, I hope you enjoy the previous tutorial about pagination in AngularJS WordPress theme. Today I want to show you how to deal with “page not found” scenario in our project. You might be a little bit surprised that we’ve sort of talked about it when we learned the “otherwise” method in $routeProvider. It turns out that we still have a few things to cover. So if you have a couple of minutes, just open your favorite code editor and get started.

0. Getting started

From the project repository on GitHub you can get an AngularJS WordPress theme last time we’ve built. If you’re new here, in the series of tutorials I just tried to share my learning path about building a WordPress theme with AngularJS. So far we’ve built one with category archives and pagination, and also a functional search form in it. You can just download it and focus on this tutorial right away, though I do encourage you to check other posts out in your spare time.

1. The “otherwise” method in $routeProvider

As I mentioned in the beginning, the first “page not found” scenario we can easily deal it with the otherwise method in $routeProvider.

Here’s the route paths we’ve set so far:

So if someone visits our site at a random location, for example, “http://siteurl.com/a-fake-path”, she/he will fallback to the “otherwise” method because the path “a-fake-pathdoesn’t match any route path. With code above she/he will be redirected to the homepage, now let’s enhance the otherwise method with two params: templateUrl and controller, just like what we did in those when methods:

Just checkout line 28-31, I set a new template 404.html and a new 404 controller, let’s see what do they look like:

Please note the 404.html should be in the partials directory, and the 404 controller should be in your scripts.js. Now if you visit the site with a fake path, you’ll see our 404 page like this:

Display a "page not found" message when a location doesn't match any route

2. When a post doesn’t exist

The second “page not found” scenario is that a visitor may come to a page perfectly match a route path, let’s say if someone visits a post which have been deleted, the location should match our “/blog/:ID” path, but AngularJS will fail when requesting the post from WP REST API with the $http service.

If we just leave it alone we’ll get a blank page when we visit such locations. It’s very confused to any visitor so we should definitely improve it.

Blank page when a post doesn't exist

In such cases (the route path matches but the post doesn’t exist), we can use the error method in $http service to get the error response from WP REST API:

At line 8-14, I did the following things:

  • line 8: Besides res, we also add status parameter to the error function.
  • line 9: When the error status is 404, a typical “page not found” status code, we’ll manipulate our view to notify our users.
  • line 10-12: We add a new property to $scope called is404 and set it to true, change the document title to “Page not found” and add an errorMessage property which is the error message we get from the response.

After that we also need to update our content.html template so we can display the error message when the post not found:

You can see that I use ng-if to conditionally display two divs based on the is404 property. Now when we visit the sample post above again, we can see why it is not found:

Invalid post ID

The WP REST API provides very clear responses so we can easily spot the issue. For example, if we change the post ID to a string, WP REST API would send us a different error message:

No route was found matching the URL and request method

3. When a category doesn’t exist

Now you get the idea that we need to check all route paths to ensure there are corresponding “page not found” messages for each of them.

If you try to add an error method like we did in the Content controller, you would be surprised that it didn’t work. That’s because when we use the endpoint “taxonomies/category/terms/?filter[slug]=slug-not-exists” to get terms, it will return an empty array instead of error responses if the term doesn’t exists.

So in such cases, we’ll use a different approach to deliver our error message:

At line 10-13, we check if the response is an empty array, if so, we set the document title and the pageTitle property to “Category not found”. And we also add a new paragraph to display the error message in the main.html (at line 17):

The result page would be like the following screenshot:

Category not found

4. When a paged archive doesn’t exist

The last “page not found” scenario is when a paged archive doesn’t exist. For example, if you change the “posts per page” settings to a larger number, like from 6 to 10, paged archives with higher numbers will be missing.

It’s kind of funny that we have to use another approach to check if the page parameter is correct. Atn line 12-15, we do so by checking if currentPage variable:

  • isNaN, which means if the currentPage variable is “Not-A-Number“.
  • larger than the headers(‘X-WP-TotalPages’). If so, such pages should not exist.

And we update the document title and pageTitle property accordingly.

Don’t forget that we’ve also created the category paged archive from last tutorial, so let’s modify the Category controller again (at line 24-27):


It’s not just about “page not found”

I hope now you get the idea that why I’m writing this tutorial to talk about all scenarios, because it’s really not just about “page not found”. As a developer we should also consider user experience whenever we can, so providing descriptive error messages is the least we can do.

I promise you in the next tutorial I’ll show you how to tidy up our scripts.js by creating an AngularJS service. In the meantime, you can download the final theme from the GitHub repository and have some fun.

Don’t hesitate to contact me if you have any question when following these tutorials I wrote. I’ll get back to you as soon as I can.

23 responses

  1. gaggo Avatar

    Just wanted to tell you how great your tutorials are and that I can’t wait for your next post!!

    best from Berlin

    1. Yoren Chang Avatar
      Yoren Chang

      Hey I’m flattered! Just stay tuned, the latest tutorial will be out this week. Talk soon!

  2. Daniel Avatar
    Daniel

    Yoren,

    In my Routes I have the otherwise to redirect to the home page but when you go to a route that is fake as you mentioned such as:

    http://blogurl.com/fake-post

    Its using the content controller and the content.html partial rather than getting to the otherwise route. I have followed along with your tutorial so i’m not sure where I’m going wrong. The route for the content is “/:slug”

    Any Ideas?

    1. Yoren Chang Avatar
      Yoren Chang

      Hi Daniel,

      If you set the content route to “/:slug” without any prefix, the otherwise route won’t work cause any path will be considered valid – they’re all match “/:slug”.

      Change to something like “/blog/:slug” and see if it works. Cheers.

  3. Jesper Landberg Avatar
    Jesper Landberg

    Does this work on single pages (content.html) for navigating between posts?

    1. Yoren Chang Avatar
      Yoren Chang

      yes, of course. I think it falls into the type I mentioned – “2. When a post doesn’t exist”.

  4. Hi yoren,
    Do you have a configuration for remove the ‘#’ I have used this one
    http://www.w3sanju.in/remove-hash-from-angularjs-url/
    but does not work properly, everything woks fine but when I copy and paste the url in another windows.. does not load the script… do you know what is it the problem?

    David.

    1. Yoren Chang Avatar
      Yoren Chang

      Hey David,

      Are you still working with a WordPress theme? If so, please make sure you’ve update the Permalink Structure in your WordPress Settings. I’m sure if you’ve followed my tutorials, the # should be removed by default.

  5. Hi again Yoren,

    I’m getting the 404 from wordpress when trying to route to a post ID. Any ideas how to bypass this and get the request sent to the angular router?

    Thanks again for terrific learning materials so helpful!

    1. Yoren Chang Avatar
      Yoren Chang

      Hi Tom, please send me a copy of your theme to yoren[at]1fix.io so I can help debugging. Thanks.

  6. Hi Yoren,

    Great tutorials, thanks! How do you manage browser refreshes? I’m getting a 404 when I refresh a page on any other route the the root route. So say I navigation to http://www.example.com/mypost and refresh that page I get a 404. Any tips on how to handle that?

    Cheers!

    1. Yoren Chang Avatar
      Yoren Chang

      Hey Barry,

      If you’ve done things right, you shouldn’t get 404 when refreshing pages.
      Do you set the right permalink structure in your WordPress? It should be identical to the routes in your AngularJS app.

      I doubt there might be something wrong in your AngularJS scripts, just paste it to Gist so I can check it for you.

  7. How can we Post in angularjs using type script or with out it.
    I am trying to write to Json file using the post method but it gives me error “POST http://localhost:1989/client/app/travelrequest/Json/data.json 404 (Not Found)”.
    When i try to read the Json file with Get method it works.

  8. Sorry, I am so busy to find a solution that I even forgot to say Hi.
    Hi Yoren.

    1. Yoren Chang Avatar
      Yoren Chang

      Hello, Ankur,

      To use POST / PUT method you need to be authenticated. It’s a more advanced topic please refer to WP API documentation first: http://v2.wp-api.org/guide/authentication/.

      If you’re building a WP theme or plugin, you can see if this post of mine helps: https://1fix.io/blog/2015/10/11/cookie-authentication-wp-api-angularjs/.

  9. Benjamin Avatar
    Benjamin

    Hi Yoren ,
    Great what you are doing to help some like me. Yes I have doubt about ionic and angularjs , so I was working a while to know how to get single page of my wordpress blog.
    Do you have plese any idea?

    1. Yoren Chang Avatar
      Yoren Chang

      To retrieve a page, use the endpoint: /wp/v2/pages/

  10. Benjamin Avatar
    Benjamin

    Thanks you YOREN

  11. Hi, I had a question about “Page not found” issue after adding the $locationProvider.html5Mode(true); method to have the pretty URL. My app seems to work fine going from home page to about page. However, when I go from home page to about page, and refresh the browser, I get a “Page not found” on the browser tab. From what I am understanding, the pages are being routed correctly but when I click on the browser refresh, the browser is not able to find the url without the “#” due to html5mode pretty URL way. Please help

    1. Yoren Chang Avatar
      Yoren Chang

      Hey Alex, did you set your WP to use “pretty links” in your Permalink Settings? That should fix the issue.

  12. Yes I have tried that. I was wondering, I am using $stateProvider instead of $routeProvider. Do you think this may be the difference? Also, from googling around, I see that the issue may be within the .htaccess file. Is there a way this file needs to be read for routing with $stateProvider? Thank you for your help.

  13. Hi Yoren, I have create a live version of what Im trying to accomplish. http://template.webpromo.com/wpAng_test/

    Basically, from landing page click “GO TO – About Page”>
    on About page, if you click browser refresh, “Page not found” is displayed on the browser tab.

    If I remove the $locationProvider.html5Mode(true); in my “angular-theme.js” the hash tag reappears and there is no problem. Hope you can help out. Thanks in advance

    1. Yoren Chang Avatar
      Yoren Chang

      Hi Alex, can you take a screenshot of the permanent link settings for me? This is very typical that WP is telling you the pretty link structure is not working.

Leave a Reply

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