Check out a free preview of the full Vue 3 Fundamentals course
The "Fetching Data in Lifecycle Hooks" Lesson is part of the full, Vue 3 Fundamentals course featured in this preview video. Here's what you'd learn in this lesson:
Ben demonstrates fetching async data in Vue and walks through a diagram of how a lifecycle hook works. A student's question regarding if the lifecycle hooks can be paused if a promise is not returned is also covered in this segment.
Transcript from the "Fetching Data in Lifecycle Hooks" Lesson
[00:00:00]
>> So let's go ahead and jump back into the code. As we can see here, we have a lot going on right now. And since we're talking about kind of a new concept in regards to fetching async data, let's go and clean this up a bit, right? So I'm gonna migrate this over into a separate scratchpad.
[00:00:15]
And so instead of components, I'm going to just create a scratchpad.vue file and we're just gonna migrate everything from App.vue over. And that way you have that as reference for later on if you wanna see exactly what happened. So clean this up and keep this a standard New, basically a New App.
[00:00:37]
Great, and I'll go ahead and commit that to the branch. Let's see, refactor move code to scratchpad, all right? Great, all right, so the question here is, the data we've been working with so far, if we take a look at scratchpad, everything is something that we've defined ourselves.
[00:01:01]
And we're assuming basically that we always have full control of the data. And if that were really the case for front end development, I think it allows would be a lot easier. But the reality is we have to fetch data from the backend a lot of times and we got to figure out how to deal with that.
[00:01:13]
So we've we take the tools that we have right now and think about how we might do that. Let's go ahead and use the Pokeapi, which is one of my favorites when it comes to working with sample data, because I think Pokemon was a fun thing for me growing up as a kid.
[00:01:26]
And so basically, this is a pretty impressive database in terms of being able to fetch things about individual Pokemon, fetch it by region, it's darn impressive. So, the URL we're gonna be using, I'm gonna go ahead and add a comment up here is, this pokeapi.com. And you notice the main thing is that it just fetches the Pokemon, and it limited to the first 151.
[00:01:46]
So in other words, the original 151 Pokemon. So our first goal here is to say, okay, how do we fetch that data down from the back end and actually render it onto our page? Well, first thing first, let's go and set up our app real quick. We'll export default and object.
[00:02:00]
And for our reactive data property, let's go ahead and just have a Pokedex array. And then again, let me actually add some items in here so we can actually see it when we show it on the page. Let's go ahead and show that real quick to make sure everything's wired up correctly.
[00:02:15]
And there we go our array's showing up. The next thing we wanna do is add some sort of method, right? Because we need to actually call this thing, so you might think okay so we have a method called fetchPokemon and it will use the fetch API and then we'll go ahead and grab this URL up here.
[00:02:32]
Oops, there we go. And then what we need to do though is that ,oftentimes when you fetch data from the backend, you need to actually JSON a file. In other words, you need to convert it to JSON, so you can actually parse it correctly on the frontend. And so the way you do that is you take the response that you're given, and you do response.json.
[00:02:47]
And so what we wanna do though is, we don't only want to fetch this, we want actually assign this to our Pokedex right? So we're gonna do this.pokedex=fetch. But we're not quite done, because what? Fetch is an async operation, and right now everything we're writing is in a synchronous operation.
[00:03:03]
So in other words here, what we got to do is we got to say, hey, we have to wait for fetch to finish before we do this thing. And since we need to await the thing, we need to actually make sure we tell Vue, hey, by the way, this is an async function.
[00:03:14]
This is gonna happen asynchronously. Great, we have our method and so, all right, we wanna fetch the thing, right? So we have a button and when we click the button this is when we wanna run that fetchPokemon. So fetchPokemon like that. Great, let's see what happens now. If we click, hey, everything's there, just as we expect, this is exciting.
[00:03:35]
But if we think about the real world scenario, while there are cases where you'll be running async functions on specific user interactions, the reality is a lot of times when someone's loading a page, that's probably when you're actually gonna be wanting to fetch that data. And more importantly, you want to fetch it at a specific timeframe.
[00:03:51]
And so this is where the concept of lifecycle hooks comes into play, when we're talking about frontend frameworks. And I think most of them do have them. So, let's take a look at the diagram for lifecycle hooks for vue. And we're gonna take a look at the one directly on the docs, because I want you all to be able to kind of get familiar with the docs.
[00:04:05]
Because Vue has an entire team dedicated to trying to make sure that the docs are as top notch as they can. And that basically this information is free and available to you whenever it's time for you to dive into these problems. And so if you take a look at here, here we can see an actual diagram of how the lifecycle works.
[00:04:22]
And so you can see the Vue what it starts to do is the render kicks it off, and then it runs a setup lifecycle hook, which again we'll talk more about later. But you can see that what it's doing is, it's going through and at each of these steps where you see the rounded outlined rectangle.
[00:04:35]
So we have setup before created, before mount. All of these are different points inside of the lifecycle of a component. And what that mean is, you can actually basically interject different code, depending on where you need it to run. So for example, you see here that what is it doing?
[00:04:51]
First it starts to encounters a component, it starts to initialize the options API, and then starts to do some checks, basically, right? And then it starts to render the component. It'll actually mount the thing to the actual window. Basically, you start to actually see the thing. And then finally, if you're deleting something, it will unmount the thing from the DOM.
[00:05:09]
And so to be clear, I do not expect any of you to understand, the effect of what's happening here. But suffice to know that you can refer to this at any point in the future when you're trying to get a little bit more nuanced about where you want your code to run.
[00:05:24]
For the purposes of our exercise though, we have to think about it like this if we wait for the component to mount before we actually start running the code to fetch, we know that asynchronous calls can take a while. And what we wanna do is try to improve our user experience by ensuring that users get that data as quickly as possible.
[00:05:40]
Which means what? We wanna actually try to initiate that fetch before the component even renders to the screen. That way you call it, we try to time it so that by the time the component hits the screen, you're hoping that the async data basically has hopefully finished by then.
[00:05:51]
And so if we take a look at where that is, basically the way to think of it in your head at this point is the mounted lifecycle hook is when it's basically showing up on the screen, that's the way to think about it. And so in other words, you have the ability to say beforeMount, there's one right here.
[00:06:08]
But then there's also a couple of steps happening before beforeMount. So actually we even have the created lifecycle hook and the beforeCreate. But there's a key thing that you'll notice here though, is that with beforeCreate This is happening before the Options API. And so what does that mean?
[00:06:23]
I think it'll be easier if I show you this inside of the code. So let me go ahead and bump this over. Okay, so if you take a look at this right now, we mentioned yesterday that passing an object in order to define how our component is working is called the Options API.
[00:06:39]
Cuz we see here there are data, there are methods. And so similarly, we have the ability to call lifecycle hooks on there. So we have, what do we see earlier beforeCreate was one of them. And so beforeCreate can be a function that we run. So all I'm gonna do here is I'm gonna log beforeCreate and then we're gonna try to log this.pokedex.
[00:07:01]
And then we're gonna log the created lifecycle hook. So this is basically how you're going to call the individual lifecycle hooks is by basically the name right here, that we see here this is a little small right now because of the mobile responsive. And then just basically calling it as a function, and that's how you actually reference it.
[00:07:20]
So when created now we'll do a log create. And then design this is when it's been created. And this time we'll log this.pokedex. Okay, what's gonna happen here? Well, if we take a look inside of our dev tools, you'll notice something here. Is that before create gets logged, but then this.pokedex does not exist.
[00:07:44]
However, then once created does, you'll see .pokedex does exist and inside of this proxy here, you'll see the inside of the target, which you wanna open up. That's where you'll see the actual value of what's happening. And so we think about it in another way if we rearrange this for our mental model.
[00:07:59]
Before create is actually happening, all this stuff below here even exists. And so if that's the case, that means that when you're using the options API, beforeCreate is probably not actually the best place to be running an asynchronous function, because at this point, nothing exists. So what we wanna make sure we do then, is to basically say when it's been created, remember crate is not the same as mounted.
[00:08:19]
There's a bunch of stuff happening before it's actually mounted to the page. Once it's been creative, this is where we're gonna say, let's kick off our function. So we can do is we can then go this.fetchPokemon. Now we save this though, you'll see, boom. All of a sudden without clicking anything, it did exactly what we wanted to.
[00:08:38]
Which is, the user hit the page, the vue did its thing to go fetch the data, it immediately showed up on the screen. Okay, How do people feel about those concepts, that makes sense? Question.
>> Are those hooks promise aware if you were to return the promise to this fetchPokemon, would it pause continuation until it returned?
[00:09:03]
>> So your question here is around whether the lifecycle hooks are aware? Could you actually could you returned a promise instead?
>> Yes, would the created not continue until the promise resolves. If you want to do for some reason not but until the promise is fully resolved?
>> Before you actually move on to the next hook, basically.
[00:09:20]
>> Yeah.
>> So in this regard you don't want so run it. I don't see why that won't be possible. Vue usually has ways for you to break those things apart so that you can basically stop it. And so to be clear this is a little bit beyond the scope of the intro.
[00:09:36]
So if this goes a little beyond what your current knowledge, don't worry. But basically, if you've heard of things like nextTick inside of code bases, that's where people are manually initiating different stages to ensure that either different frames are being skipped or moved on. And so just know that if you're trying to intentionally stop it at the lifecycle,
[00:09:54]
>> [INAUDIBLE]
>> You probably have to dig into it just to figure out how that will work. Cuz normally, Vue as you can see, it tries to optimize it. Cuz normally you might even expect at this point, let me go back to the code, and close up. this.fetchPokemon is an asynchronous function.
[00:10:09]
And so here's the thing, if we were to call the fetch directly here, and we did an await, okay, So let me do this real quick. And then let's just const response= this, and that says log response, okay? So, all right, you'll see already that vue is yelling at me because if you actually manually define it in a way keyword inside of a lifecycle hook, it will ask that you actually defined the async on that directly.
[00:10:45]
However since we're not doing that since we actually have the async already defined on the function, this is why this code still works. But otherwise to your question, and yeah, I would just dive further in into how to get it to pause, but otherwise you should be able to do what you want.
[00:11:00]
So when it comes to lifecycle hooks, basically I would say the ones to really know about are created. Because that's usually where you're gonna be running your async functions. And then if you really have something that you really want to happen right when the component is mounted, then I've seen a lot of beforeMount or mounted used for those scenarios.
[00:11:15]
We might want to time either some sort of animation or that kind of thing. But otherwise, just know that create is kind of gonna be your bread and butter when using the Options API for doing asynchronous calls.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops