Subscribing to Variable Changes in Weweb (@weweb_io)

Ray Deck shows how to subscribe to WeWeb variable changes using the Vue store's `store.subscribe` method. He builds a helper function that fires callbacks only when a specific variable's value changes, then tests it with multiple variables in preview mode.
Chapters
Hey, so we had a request from a viewer on the channel saying that this is a session we did on connecting WeWeb variables was super helpful. They want to know if you could bind events, right, to changes in a WeWeb variable. Like you can do inside WeWeb itself, or you can use that, that plug to associate the variables that are in a given thing like the button up here. So if I were to, you know, go back over here and click in here, the text of the button is bound to the counter. Every time the underlying variable changes, this, this field changes as well. That's fine inside WeWeb, but what happens when you're trying to bring some stuff from outside WeWeb to the party and you want to connect the WeWeb variables? You want to get that same kind of behavior. We talked before about using, being able to go into DevTools. And we talked before also about using wdevlib, and we talked about wdev_variable as providing us with a lot of utilities that were pretty handy, including get_value and update_value, allowing us to read and write variables from WeWeb and into WeWeb. And I suppose there's probably a naive way we could do this where we could use some sort of setInterval and just be watching for changes in that variable all the time, every few hundred milliseconds or something like that. And while that's certainly available to us, there's a more direct path that actually lets us look inside how WeWeb works. Now, we need to remember that WeWeb, and WeWeb tells us this when we go over to, you know, developer.weweb.io, WeWeb is going to be, is a Vue application. It does Vue.js. And when we go take a look at WeWeb, and we say, let's back off of dub dub variable for a second. Let's just look at this dub lib sort of top-level object. It offers us a number of things that are sitting inside it, including like the, you know, Apollo, presumably GraphQL client. It has some of the dub dub things we talked about before, which are the opportunity to work with the dub dub variable and being able to trigger workflows, those kinds of things. But the other thing that we have available to us directly is actually the store that it uses as a Vue.js application. And that's an interesting place for us to be because if we were then look up, I don't know, Vue.js store, and obviously I've done this before, we can see there, there's a very common Vuex store that is the main way that the Vue applications like to manage their state. So the information sitting in there is gonna be changed, be able to dynamically reference what's going on. My impression is it's like Redux for React applications. But it is, it is also something that has recently been deprecated in favor of another application, which is called Pinia, Pinia, or another library. And, but the Pinia library seems to use, it stacks on top of the same principles. So this is where we're going to find the store. Now, once we found the store, the next question is how can we go have a conversation with the store without having to make our own view component? And there is an API reference here that we can use for that job. And there's access to creating the store and state and mutation actions. And yeah, these are the kinds of things I would associate with a data state manager. Being able to pull data out or access to getters, modules, plugins, all sorts of good stuff in here. And then there also, what we have are these methods, right? With like these commit, dispatch. These are ideas I would associate with we're going to make a change to the state, which fortunately when we're dealing with variables, we can just do it with the update variable that we already did previously in the dub dub variable. So it wraps away that concern. But what we haven't wrapped away is the question of being able to subscribe to changes in the variable. So are there good options in here that would let us take a look at that? We see commit, dispatch, replace state. And the question I'd ask is how do we get access to the store? So, oh wait, hey, it's commit. Dispatch getters. It seems to have a lot of things we were just looking at inside this functionality and inside this page. So I would take a reasonable guess we would have access to something called watch and we also have access to something called subscribe. Now I will tell you that in my experimentation, I was trying to make watch work and I couldn't get it to fire each time I changed the variable. It only seemed to fire the very first time I made a, made a connection to it. So this is probably me not quite understanding how watch works yet, and that's fine because subscribe gives us a callback that fires every single time the, the underlying store changes, which can be really handy. Okay. DodoLib store.subscribe. Now here's the thing. Subscribe. I actually was doing this wrong a second ago, but Nevertheless, we'll, we'll do it wrong again. E, T, and we'll just say console.log E is E, T. Okay. And then now we're, we just have a, we're subscribing with a function that's just going to every time this changes. We're going to fire off this function, we think maybe. So let's give this a try and we'll put this into preview mode and look, it's just giving us all sorts of errors. And the reason for that is 'cause I did it wrong. And that's because over here you can see the subscribe actually just takes the handler as a single argument. And that's because it's gonna fire every time anything at the state changes. So I'm not passing it actually to one variable that I care about. I should do here and just watch while I do this is I will just backspace over that variable I was trying to watch. Okay, now let's try it again. Okay, it's giving us lots of error messages because I put something bad in before. So we're just gonna refresh this, right? And then we'll go and put this in preview mode and Run it again. Oh, wait, I haven't actually run the subscribe. So we'll do the subscribe and look at that. It's giving it every single time anything changes about the store, right? Being all these things are changing, including by the way, the variable that we want to change. And in the course of any of these, it's going to tell us both about the payload of what was supposed to change. In this case, it was that particular variable ID. And what the value is supposed to be. You can see over here, if I were to go and go back over to here and take a look at counter 2 and copy the ID, and I don't know, let's put it over here into a URL just so you can see it. You can see it's that AF40 thing, and this has that AF40 thing. So this, this subscribe event is going to fire for everything that's going to change in the store, which includes setting variable values. And as you can see, a whole bunch of other things you don't necessarily care about so much. So that means we can subscribe to the fact that it just changed. So I can see that -3 happening here and I'll just turn it to that and make it into a -4. And you'll see up here we have the variable value and change it to a -4 and what the variable ID was. That's all fine, but it's not exactly what we are looking for 'cause this is giving us every single possible event. So we're going to need to filter it down to only be when our variable changes. Now, this actually gets to a really interesting part about subscription, which is that the subscription is going to give us this handler function. Actually takes, it has certain arguments to it, and those arguments are going to give us the value as well as the what mutation was, but also what the new state is down. And that means so every time we change anything, we create this new state. Object which will contain our variable as well. And that's pretty cool too. So let's go into here and we click on my TS, right? So let's take a look at the T part, right? It says it's a proxy object, which is not as exciting as it could be, but we click on the target to find out more about what's inside it. And in here we can see there's data and inside data we can see variables. Inside variables we see our variable and our variable has a property called value. So now we can be studying the variable that we care about and its value. And what's, what is that state of it inside the application? And then we can be comparing it with when we actually make a change in this particular value. So this gives us our baseline for what we need. We're going to work off of, so we're going to use store.subscribe, but we want to filter it down so that it's only going to report out when our variable is actually the one that's doing the changing. This becomes where we write just a little bit of code. And that code is basically to create our own subscribe function that's going to have the job of paying attention to when we make changes. So this is a little bit dense, but let me walk you through it for a second. The, so we're saying whenever our particular key changes, we want to fire our callback and that callback, by the way, can then do whatever it is you want in your, your outside WeWeb code, right? This allows you to bind your events inside your external bit of code to the information that is coming from WeWeb. We say that we basically just initialize a store of subscribed values just for the purpose of our own little subscriber here. That way we'll be watching for how those variables change with time. So we will subscribe just like we did before using the E and the T. And we'll ask if the event is a set variable value. That's important because that's going to be the kind of thing we're going to pay attention to because that means a variable got changed. Now we're going to ask, okay, let's take a look at the data from the variables and the variables key. We're going to ask what that value, because when we're looking at the variables, variable key, the value, right, this is the negative 4 part, that value is equal to that which I'm keeping in my little temporary store called— I'm calling _subscribe_values. And if those two are different on a shallow basis, which really means a pointer basis, if it's two different numbers or two different strings or a true to a false, all those things will cause it to say, yep, those are different. You could have a mutated object that actually might report being the same thing because that mutated object would be basically the same pointer in memory.. But generally we're relying on WeWeb to make sure it does things properly and create new pointers as it mutates objects. And in general, it does that job pretty okay. And then we say, if those two things are the same, then let's set the subscribed value. And then we're going to fire the callback, which was our second argument. So it'll take a function as an argument that's going to trigger only when our value changes. Remember, every single time there was any change to state, we saw all of these subscriptions fire out. So we saw all of these me, my, my, my, my, right? That's, that's because when we just do a basic subscribe, it was showing everything. But let's try using this much, much more limited version of the function, which is only going to fire when it's our key that's changed. Highlight all that, copy, and in WeWeb, Paste, enter. All right, so this is now defined, dub dub subscribe. Let's have it work with that second one, that counter 2, just like we talked about. Copy ID. And then we'll again use arrow syntax for the callback and we'll call it new value. And the, and we'll say console.log, and now I've subscribed to that newValue. So now when I click this, nothing really happens. My newValue is -1. So it'll keep on changing as long as it takes. I just click this, know my new values. That's why it's only subscribing to the correct one. Now I could also have a different one that's gonna subscribe to this, uh, counter. I'll copy that ID. Now it will identify it's actually for counter. Great. And now we'll go back over and, you know, look at this again. See, my new value for counter is 678, and my new value here is just 17. So we get different callbacks for different variables. That way we're keeping everything very separate. I think this is what the watch is supposed to do. We just couldn't quite get to work. And that is, and that's the crux of it. So the way I was able to go about this was by hacking WeWeb just a little bit more by saying there's this top-level dub dub lib object and looking inside dub dub lib to see where information comes from and being able to separate the things that make things convenient, like dub dub variables, which was very convenient to work with, and look for the lower-level ways of accessing it, like looking at this store. And it stands to reason the store is going to control state. And then by matching that with just searching for Vue.js and store and finding this very common state management library, start to look for common function names because then I was able to see those common function names. One of the things you'll notice in here is that it doesn't show the word subscribe yet. And we'll need— and the— and so we were able to look at that by going over to the documentation and then having figured out which things seem to work. Create just a little bit of code that we can then work with and insert into custom code or put this into a WeWeb page load action or what have you, sort of the same way we do with the, with the WeWeb embeds that we've talked about on these videos before. And the, and this could be very handy by itself and we'll have a link to it using the, the, the public version of it. There we go. And this will be available through the resources on the, on the narrative and description of the video that comes below. We've gone deep into hacking WeWeb. You now have the ability to do some subscription in your external code. And I hope you find this helpful and let me know in the comments.










