In a server-rendered application, if you attempt to load data before the page renders and the data fails to load, your application will not run unless you handle the error properly. This lesson walks you through the options of handling load errors so that your users will always have a good experience.
It's quite possible that this initial request to load data could return an error, or is the wrong URL or something, which would then cause our website to completely blow up because this is trying to server render this data.
If you try and server render improper data, then it simply can't render it and will throw a terrible error for your users. What we can do here with asyncawait is actually just try-catch it. We can try this, and if that fails like it's doing right now, we can catch the error.
A graceful way of handling it is just to say store commit, and initialize the data with an empty array. When I save and refresh here, you'll see our main page with an empty todos dataset. If I add this back so it succeeds and refresh, you'll see we get our data.
If this fails, I'll save and refresh, you'll see that we get no data, we just get this empty array. Or, we can just add a new page in our pages called something like error, make sure we have a template, div. Oops, our services are down.
Then in our index, along with the store, we also get redirect. Redirect can just say, well, it's not even worth coming to our site right now, so just send them over to the error page. With this, when I refresh, they'll see, "Oops, our services are down."
If I fix the URL, hit save, and refresh...well, I mean if I refresh on the base URL and not on the error page, you'll see we have our data again. You have your choice of either requesting and storing initial data before the server render, and then making sure that you catch it if it fails.
Or instead of using fetch you could wait until the component is created. I'll grab this, copy, paste, comment my fetch out, and make sure I use this.$store, because the context isn't passed into created, and this.store wasn't ready at the time fetch was ready, so that's why it's passed in to fetch.
Now the experience, oh and you'll see I need to make sure this is async. Now the experience when I refresh is you see todos and then you see the data loaded. We'll see that again, todos, and then the data loaded. Or, the experience with fetch is when I refresh, everything is ready.
Refresh, everything is ready, and remember that flash of un-styled content goes away when you deploy to production. One last note, there is a default error page here. If I navigate to something that doesn't exist, I'll say no, hit enter, you'll see we get this 404 error page.
That's defined in the layouts.error, and you can come in here and customize anything you need to for this default error page. You can also use it from this context, so store-redirect, another thing that's passed in is an error function. Instead of saying redirect, you could just say error with a status code of, we'll just say 500 for the internal server error.
Then a message of, "Oops, try again," or something like that. I need to name this something else if I'm going to pass in an error function, so we'll just call that error. Now if I break my service, hit save, I'll come back and reload the root route, it looks like I didn't make this an object, so I'll save that again, and now refresh.
You'll see we get the 500, "Oops, try again," which is that error layout that you can customize. However you want to, you can handle that error. I'm going to use my redirect.