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-path
” doesn’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:
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.
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 addstatus
parameter to theerror
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
calledis404
and set it totrue
, change the document title to “Page not found” and add anerrorMessage
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:
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:
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:
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.
Just wanted to tell you how great your tutorials are and that I can’t wait for your next post!!
best from Berlin
Hey I’m flattered! Just stay tuned, the latest tutorial will be out this week. Talk soon!
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?
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.
Does this work on single pages (content.html) for navigating between posts?
yes, of course. I think it falls into the type I mentioned – “2. When a post doesn’t exist”.
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.
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.
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!
Hi Tom, please send me a copy of your theme to yoren[at]1fix.io so I can help debugging. Thanks.
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!
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.
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.
Sorry, I am so busy to find a solution that I even forgot to say Hi.
Hi Yoren.
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/.
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?
To retrieve a page, use the endpoint: /wp/v2/pages/
Thanks you YOREN
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
Hey Alex, did you set your WP to use “pretty links” in your Permalink Settings? That should fix the issue.
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.
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
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.