This episode is for members only

Sign up to access "Alpine Store Basics" right now.

Get started
Already a member? Sign in to continue
Playing
03. Store basics

Transcript

00:00
So let's dive into the basics of our Alpine store. And the first thing that we're going to do is look at the very basics and how we can use methods to update properties in our store.
00:09
And then we're going to recreate the example that we looked at in the last part to see how this can be improved over dispatching events and picking them up globally.
00:18
Now, to get started with the Alpine store, let's create out a script tag in here. And what we need to do is use the Alpine store method and give this a name.
00:28
Now, this line here is not quite going to work yet. And I'll show you why in a minute. If we go ahead and just look at a really simple example, like a user, that's going to be the first argument.
00:37
So that's the name for the store. The second argument is an object containing any methods or properties that you want within that store. So for example, I'm just going to go ahead and add in my name.
00:47
Now, this isn't quite going to work. What we need to do is actually wait for Alpine to initialize. If we come over and refresh this and look here, we can see we get Alpine is not defined.
00:57
We can't use Alpine until we know that it has initialized and it's ready on the page. So to get around this, we go ahead and use document. And we add an event listener.
01:06
So let's go ahead and do that now. And the event within Alpine is Alpine init, or initialize is the longer version. So we go ahead and add in a closure in here.
01:16
And then pretty much anything we need to do on the main Alpine object can go directly inside of here. So let's go over and give that a refresh. And there we go.
01:23
So we've technically now created an Alpine store called user with one property on it, name. Let's look at outputting this value. So let's go ahead and create out a span in here
01:35
just with some X text. And how do we access this value? Since it's not assigned anywhere, we can't really access it.
01:42
Of course, we would have to make sure that the assignment was above this before we did that. But that's not a problem. We can use this store shorthand to go ahead and grab this.
01:51
Now, the store is called user. So we access it like this. And then we access any properties or methods on it like this. And of course, we have a name property on the user store
02:01
under this global store object. Let's give that a refresh. And sure enough, it doesn't work. That's just because we didn't initialize this component.
02:09
Let's go ahead and do that now with X data. Come over here, and there we go. We have successfully created a store, added some data to our store,
02:17
and we've gone ahead and accessed our store using the global store object. Now, if you need to at any point access data within here from your store,
02:28
what you can do is, and if we just console log this, you can use alpine.store, choose the store, and then choose the property that you want. For example, name.
02:39
If we give this a refresh, you can see that we can access the store in that way as well. So within templates, we would use this.
02:46
And then within here, we could directly access the store that we were after, which of course contains the object that we populated it with.
02:53
And then you can just access any properties or methods on here. So really, that is the most basic usage of our store. It doesn't get much more complicated than that.
03:03
What we can do now is look at a method that will allow us to update this particular data. So for example, if you were storing user data globally, and you wanted to create a form to update this user's data,
03:15
and then perhaps show their name in the navigation, let's take a look at how we might do that now. So let's create a slightly more complex example out here. So we're going to go ahead and create out a nav
03:26
just at the top here, and this is going to greet the user. So let's just create out a really quick span in here and say, x-text,
03:33
and let's go ahead and greet the user. So let's say, hey, and then let's access our store, user, and name. So that should say, hey, Alex.
03:43
It doesn't because of course, nav is again, not a help on components. Let's add x-data, and there we go. So just below this,
03:50
we could go ahead and create out a form. This is just going to be really, really simple, and we're going to have a button in here, which is going to submit this through.
03:59
Let's go ahead and call that submit, or a type of submit, and let's say update profile. Now over in the form,
04:06
which is also going to be a component. So now technically, we're working with two components on the page. We're going to say that on the submission of this,
04:15
we're going to prevent the default behavior, and we're going to go ahead and set the user's name to something different. So we're going to say store, user, name,
04:23
and let's set that to another name. Let's see what happens when we run this. So we're going to go ahead and hit update profile, and sure enough, you can see
04:30
just by accessing that property directly and changing it, it has kept that up to date. Now you can agree that this is much better than the example that we looked at in the last part,
04:41
where we had to dispatch an event to update everything. We have a central store now, all of this information, and we can go ahead and directly change properties.
04:51
But this isn't always ideal. Sometimes we would want a method in here which would handle the updating of that data, particularly if we had lots of data in here,
04:59
maybe in inputs. Let's take a look at that now. So we're going to go ahead and create our name for this, which is just name, an ID of name.
05:07
And in here, let's go ahead and create out a model, which hooks up to a form over here. I'm going to go ahead and get rid of this submit prevent. So inside of the form data here,
05:17
we would probably have some kind of form in here with the user's name, which we could go ahead and update. So we're basically changing our name. Let's hook this up to form name.
05:26
So just to kind of recap, if you're new to Alpine, X model is going to go ahead and hook up whatever we type in this input with the data that we have in this component.
05:36
Just to demo that, we can go ahead and output a span here with X text, and we can go ahead and just output the form. Let's go over and check this out.
05:43
And yeah, that's not going to work. Let's say form name. And whatever I type inside of here is kept up to date with that data.
05:52
So now when we submit this form, we basically want to call a method over on our user store to replace the user's data. Now, in this case,
06:01
we've just got a name property floating around. So it'd probably be better to switch this over to a data object with the user's information in here already.
06:10
So we're going to have to make a couple of adjustments here. Store.user.data.name. Now we have a kind of place for this away from any methods that we're going to create down here.
06:21
So let's just check this out. That all looks good. We now need to hook this up to go ahead and update the user's details.
06:28
So we're now going to say X on submit, prevent, and let's go ahead and access from our store, from the user store, an update method. And let's invoke it.
06:41
Let's pass through the form, which remember contains all of the information for that user's profile. And let's implement this method.
06:48
So this method is going to go ahead and take in the data that we want to replace inside of here. Of course, this is a very contrived example, but hopefully this makes sense.
06:58
So to update the data, we're just going to go ahead and access the data from this and set it to the data that we get through into this method. Just before we test this out, let's recap.
07:08
So we are using this new data property, which stores all of the user's information in the navigation, which outputs the default value
07:16
that we have set inside of our store. This form is going to go ahead and take in any data that we have within this form under this form object here, e.g. the name, that could be the email address as well.
07:28
And this button, of course, is going to go ahead and submit this form. So when we do submit the form, what we're now not doing is directly accessing this data
07:36
and changing it. We're calling a method instead called update, passing through all of the data of the form. And that's going to go ahead and set the data in our store.
07:44
So really, really simple and pretty much like a standard Alpine component, where if you were using a method, you would update any of the properties inside of here.
07:54
Let's go over and try this out. So I'm going to change my name to Billy, hit update profile. Sure enough, that works as we would expect.
08:02
So really the only two things that you're probably going to need inside of an Alpine store is any kind of data, which doesn't have to be wrapped in a data object,
08:10
and methods which manipulate the data, or we could even implement getters. Let's take a real quick look at that now. So a getter starts with get within JavaScript,
08:20
and we could say uppercase name, just as a silly example. Now what this is going to do is it's going to return to us the data that we need,
08:29
but in uppercase. So in this case, let's just say, return this data name to upper case. Let's just make sure that that is the correct case
08:41
for that method. I think it is. And let's look at using this. Now a getter in JavaScript just is read like a property.
08:48
So for example, we could just switch this over to user uppercase name. And if we go over, there we go. We have an uppercase name.
08:56
And of course, when we update the name, because we're now using a getter, that will automatically be transformed to uppercase for us.
09:03
So you can combine these. And if you're used to other patterns of store, think of this as your state, these as your getters,
09:11
and these as your mutators or actions. Finally, let's just go ahead and create a new HTML document in here. And I'm just going to go ahead
09:19
and grab the entire structure of this over. Let's look at the example we looked at in the first part, where we were using dispatch to update a task count in the navigation.
09:30
So I'm going to go ahead and pretty much get rid of everything inside of our store. We're going to rename that again in a moment. And then just up here,
09:37
we can pretty much get rid of this form inside of here as well. So inside of this span, we want the count of how many tasks that we have.
09:47
And then this store is now going to be tasks. Just below this, we're going to have a div in here, which will use a button to just create a new task. And we'll just keep this as simple as possible,
09:59
making sure we have X data here. And we'll just say create task. So exactly the example we looked at earlier. So if we come over to this, tasks.html,
10:09
when we click create task, that will create a new task, but it will keep the count up to date. So we can pretty much use everything we've learned to pull this together.
10:18
Okay, so our tasks need some sort of state. Let's actually call this state. I think that makes a little bit more sense. And inside of here,
10:25
it's going to be an array of the tasks that we've created. There might already be some already loaded from the server in here. Now, create task, when we click on this,
10:34
is going to go ahead and create a new task. So let's just call this create task. Now, where would we put this method? Well, you could put it directly within this component
10:44
if that made sense, if it was a form, or you could even create out a method on your store. Let's look at both options. So we're going to go ahead and say X data.
10:54
Let's bring this down so we can create a method out. And let's add our object in here and create a create task method. Let's just console log out, create for now,
11:04
just so we know that that's working. If we come over and hit that, sure enough, that works. So to create a new task, we want to access these tasks here in our store
11:15
and push one to it like we did before. So how do we do that? Well, we can use store and tasks, state, tasks, push,
11:26
and then we'll just use math random again, just to push that in. So let's output the count here, and we can do that using a getter like we saw before.
11:35
So get task count, and all that getter is going to do is return to us from the state, from tasks, the length, pretty simple.
11:48
So we can use this now in our navigation. Let's go ahead and do that. So let's go and use X text again, and let's say back tick this,
12:00
and let's say store tasks, task count, tasks, and let's see what we get. We should see three tasks, and we do.
12:10
Now, when we click create task, what that's going to do is push a task to that array of items. Let's check it out, and there we go.
12:19
Sure enough, that increment. So everything is nicely kept up to date without having to litter this with dispatching events and trying to keep your state manually up to date.
12:30
Now, because we are working with a store, it might make sense to have this create task function inside of our store because it is directly mutating our store.
12:41
You don't need to do this, but it would probably be a little bit cleaner. So let's actually take this method entirely, and let's just bring X data back to the way it was before,
12:53
and let's go ahead and put this method inside of here. So that would probably hit some sort of API. And then in here now, we don't need to reference store directly.
13:02
We can just reference this state and tasks, and then we can push an item to this. So now what we can do is when this form is submitted or when this button is clicked,
13:13
if that was a form you would just use a submit event, we can use store, tasks, create task, much cleaner. This component just shows a task. It doesn't have any kind of event handlers on it
13:26
to pick anything up. This is responsible for calling a method over on our store, and our store just has everything in it that we need. Let's just try this out again,
13:35
and sure enough, it worked in exactly the same way. So a real improvement by encapsulating everything within our store into one place, and just really two simple components.
13:48
This now means that wherever we want to show this state, we can just duplicate it and access the store directly. So now we're just keeping everything nicely up to date. And those are the basics of Alpine Stores.
5 episodes 29 mins

Overview

Forget dispatching events to keep your state together. In Alpine, stores give you a central location for data that make state management a breeze. In this series, we'll cover everything you need to know to get started with Alpine stores!

Alex Garrett-Smith
Alex Garrett-Smith
Hey, I'm the founder of Codecourse!

Episode discussion

No comments, yet. Be the first!