Intermediate Vue

Flexible Arguments

Ben Hong
Pandan Studio
Intermediate Vue

Lesson Description

The "Flexible Arguments" Lesson is part of the full, Intermediate Vue course featured in this preview video. Here's what you'd learn in this lesson:

Ben discusses creating flexible composables by standardizing return values and using types like MaybeRefOrGetter to handle various input types. This ensures consistency when working with reactive and plain values.

Preview
Close

Transcript from the "Flexible Arguments" Lesson

[00:00:00]
>> Ben Hong: So when you're creating your composables, you need to make sure that their arguments are flexible, but they have a standardized return. What do I mean by that? We had a chat earlier about how Filter Task, really, when you're looking at this, it doesn't look particularly like. In fact, we don't see anything imported by Vue at all here.

[00:00:18]
The problem is, when I mentioned flexible arguments, is that, remember, when we're calling these in our components filter tasks, let's see, where is Filter Task being called? Let's bring up an example. In this particular case, it's actually passing like a task object. But what if newTaskStore was a ref of tasks?

[00:00:53]
In this particular case, you're actually gonna get an error because what you told JavaScript is that I'm passing you an array of tasks. But at this point, it's technically not an array of tasks, it's a ref that contains an array of tasks. And then, uh-oh, I guess I'm seeing some.

[00:01:15]
I'm gonna let you sit with that for a second.
>> Speaker 2: Would that be corrected if you passed in the value of the ref?
>> Ben Hong: Correct. If we did it like this, now it's solved. But this is why the recommendation here is to be flexible about it. It's because you can't really guarantee how your developers want to use it, and it will always feel a little clunky.

[00:01:38]
And so Vue thought about this. You know, we see that people are going through this, so how might we solve this? Well, it's actually kind of clever. So we have here, we said that it's a type of task, but we also know it might be a ref. So in Vue, we have this type called mayberef.

[00:02:06]
And so you say, maybe, maybe if it's a ref, maybe it's not, or maybe it's a plain value, one of the two. We don't know if it's reactive, but either way, we're going to find a way to deal with it. And I'll explain that in a second. Okay, so now you're wondering, right, like, okay, so what does this mean, right?

[00:02:25]
It could be reactive, meaning it's a ref, meaning it has to be unpackaged. Or it's a plain value, and then dot value would not work cuz it's already a plain value. And so this is where the standardizing what you're returning is important, because then you, as the composable author, need to decide in the rest of this composable, do I want this parameter to be a flat value?

[00:02:45]
Or do I need it to be reactive? If you need it to be a plain value, there is a helper method from Vue called toValue. So basically we would say, for example, I'll just say tasks just to make it easy in this case. ToValue on taskList, so always forces an unwrapped value.

[00:03:12]
What's nice about this is the toValue helper function, if it's not a ref, it'll just spit back the value. If it is a ref, it will unpack it and then make it plain. Your alternative, as some of you might have guessed, is to simply wrap it in a reference.

[00:03:33]
And if you wrap a ref in a ref, it just flattens to a ref. It's not like you're doing additional performance overhead. This is where consistency, in other words, you don't enforce consistency at the parameter level, where again, especially with call signatures, you just don't know what developer is going to try to call it.

[00:03:58]
So you say, cool, as long as you give me an array of tasks, whatever its method, I will then deal with it, I will standardize it, and I will follow through. And so to finish with that particular line of thought, this also means that whatever you're doing, you should then probably be consistent about whether you're usually returning a reactive value or you're returning a plain value, because that is another choice then you have to make as the author, because is this something that.

[00:04:24]
And so one would probably make the case that if it's a composable, generally you want a reactive value because it's probably dealing with state, and so you want someone to be able to subscribe to it, watch to it, et cetera. Whereas if you were doing more like a utility function, maybe logic, then a plain value is probably the route to go.

[00:04:42]
But again, to be very clear, that is up to your digression as an author of whatever composable utility function you should choose to do. But the key here is flexible arguments, standardized execution within it so that they go two hand in hand. So I do have to wrap this up with one additional caveat, and I promise it's just the one more thing.

[00:05:06]
So I mentioned that you have regular tasks, you have the irregular value, which in this case is task array, and you have your ref value. But there's also you can also technically get values from a function. And so in this particular case, you can imagine it, I think, the signature.

[00:05:28]
>> Ben Hong: ReturnTaskStore is a function that returns a task, an array of tasks. And so if you Put return tasks store in here. This is also going to error out because it is not a plain value, it is not a ref. In fact, it is a function. So we also call it a getter because it's getting the value.

[00:05:47]
So the reason I want to say this all in one breath, because I don't want people to get too far ahead of me here or just run away and start doing stuff. Maybe ref is fine, but in reality what you want is maybe ref or getter, and that completes the evolution of your maybe ref, maybe getter, maybe plain value.

[00:06:09]
And with this type, you have essentially a perfectly typed flexible parameter that can be used in whatever context. However, someone wants to call something you know, because they decide to put a function inside of your method, call whatever you're covered, and as long as you do your part in the next two pieces, you know whether it's flatten it or make it reactive, you're good.

[00:06:33]
You're Gucci.
>> Speaker 2: Wouldn't you have to call it if. It was a getter?
>> Ben Hong: No. So that's the funny thing. ToValue and ref will just do their thing, yeah. So that's the beauty of standardizing it at the very top. You're like, I'm working with reactive values. Boom, this is what I'm doing, or, nope, just plain value.

[00:06:57]
>> Ben Hong: I was talking to the team. I really wish we could have called it MaybeReactive cuz I feel like that would've been good enough. But unfortunately reactive is already a term in view, so it would technically be misleading. But I feel like that's really what we're saying, is it's maybe reactive, but unfortunately that ship has sailed, so this is what we get.

[00:07:16]
Anyhow, yeah, any questions about this pattern of flexible parameters but standardized outputs?
>> Speaker 3: I mean, maybe it's just me, but flexible parameters, it sounds a bit like a drug looking for a disease state. Somebody wrote this really cool method called maybe refergetter and said, how should we use this?

[00:07:39]
>> Ben Hong: I think part of it is that we encountered people being inconsistent with how they were calling this function signature. And because a lot of times you're using these in components, people were passing reactive values. But then they weren't handling it correctly inside of then the method, right?

[00:07:54]
Cuz some of us, for example, I tend to default to reactive values. But then if I happen to take a signature where they're expecting plain, then it just kinda botches the whole thing up. So rather than having these sort of if else statements, they came up with these helper functions.

[00:08:10]
But again, I think if your team doesn't have that problem, cool. If you're like, every composable is a ref, don't pass it anything but plain and you all can stick to that, I mean, great.
>> Speaker 2: That's what TypeScript is for, right? To help us.
>> Ben Hong: That's fair. Yeah.

[00:08:25]
So I guess you could say you could make the case that this is really maybe more for library authors than I've just been on some co. Like some teams where like, you know, your developers halfway across the world and they're doing tickets, you know, and so like if the communication is not always there and the standards aren't as easily enforced, then things like this can help to reduce friction.

[00:08:46]
But exactly to your point, if your team is already using TypeScript in a way and it's consistent, don't even worry about this. It's just nice to know that this is an option for you, I guess is what I want to. It's so much honesty of my team teaching philosophy is to just give you tools and different scenarios where it might be useful and then you'll know best when it's time to use it or not.

[00:09:05]
>> Speaker 2: What does Typescript tell us on the other side of maybe ref forgetter?
>> Ben Hong: Yep. So it's the basically for those who don't know, T is just a generic basically variable letter, essentially any type. So yep. It essentially says it's maybe ref of T computed ref t function of T or just T itself.

[00:09:26]
So it's a very elaborate. I think they call it union. Right. I think it's a union type.
>> Speaker 4: Should we also create a parameter in the composable to allow the user to choose the filter or how to filter.
>> Ben Hong: Are they referring to this one right here? Cuz I think this is what's this TaskFilter.

[00:09:46]
Are they saying that this should also be a maybe refergator? If they are, they are correct. At least if I'm using my pattern that I'm explaining right now, is this what they're referring to?
>> Speaker 4: Yeah, I think that's what they meant.
>> Ben Hong: Yeah, yes, so to who said that in chat, you're spot-on.

[00:10:03]
Yeah, so even more about consistency, don't MaybeRef or get a one and then not MaybeRef or get at the other. Like all flexible or just be very consistent. Actually either way it's about consistency. That's the number one thing. Consistency is the name of the game.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Start a 5-Day Free Trial