Vue 3.0: Debugging composable functions
Published: 2021-03-28 18:29:47

The **composition API** is a core feature of Vue 3.0 (*though it is also available as a plugin for Vue 2*). It provides an alternative syntax for writing Vue.js components. Vue developers are used to the options API where each component may consist of one or more options such as data, computed, watchers, mixins, directives, filters, extends, and lifecycle hooks.

Recently, I have been creating Vue components using the composition API. I must say that it has been an awesome experience. This is because the composition API offers a better and cleaner way of composing **reusable code/logic** across your Vue application. These reusable codes are commonly referred to as **composable functions**. You may already be familiar with  **mixins**. Unlike Vue 2 where mixins were mostly used to create and share reusable logic, **in Vue 3.0 writing composable functions is the real deal!**

**The purpose of this article is to share with you two mistakes I have made while writing and using composable functions.** And of course, they caused bugs in my app. They may seem quite trivial but these are potential sources of bugs that you should be aware of.

To demonstrate how to avoid these gotchas, let's build a simple login component with two logical concerns: **form validation** and **API consumption**.

![login form](https://res.cloudinary.com/rxleenk/image/upload/v1616951286/form_rzqhr4.png)

![login form](https://res.cloudinary.com/rxleenk/image/upload/v1616951296/form-2_esnx0a.png)

![login form](https://res.cloudinary.com/rxleenk/image/upload/v1616951306/form3_n6ooft.png)

I used TailwindCSS for the styling. Don't mind the placeholder text **"Pharmacy email address"**. The template code is an excerpt from a project I'm working on 😉

{% gist https://gist.github.com/timothyokooboh/0950585e6d083eba18658a2160a862ac.js %}

Below is the script section **before refactoring the code to use composable functions**. As earlier stated, there are two logical concerns: **form validation and API consumption**.
{% gist https://gist.github.com/timothyokooboh/72d40485a1f4e6d7c7fc44b1c355d734 %}
I used **vee-validate** to validate the user's inputs. With vee-validate's **useField** method, I created *email* and *password* fields which are connected to the template via v-model.
With the help of vee-validate's **useForm** method, I validated the email field to ensure that it is required and is a valid email address. The password must be at least 8 characters long. 

**Now, let's refactor the code to use composable functions!**. To do so, let's separate each logical concern into its own file.

For this demo, I placed the validation logic into it's own file.
**demo-validation.js**

{% gist https://gist.github.com/timothyokooboh/09101b5868194f9af2635c932ff10329 %}


For this demo, I placed the login API call into it's own file.
**demo-login.js**

{% gist https://gist.github.com/timothyokooboh/f44c49dcde88fbd8ec2a235fa4854baf %}

Now, let's make use of these composable functions. To do so, we just have to import them into the component and destructure the values that were returned from the composable functions.

{% gist https://gist.github.com/timothyokooboh/99e91c7ba267d34592345c7b3df723ec %}

Simple right? 😀

**Mistakes to avoid**

Here are two mistakes you should always avoid: 

a. After importing your composable functions into the component, **Don't forget to invoke them inside the setup function**. It's not enough to destructure returned values from the composable functions. **You must also add brackets after the functions**

  const {
            email,
            emailErrorMessage,
            password,
            passwordErrorMessage
        } = FormValidation **()**

b. When passing arguments to a composable function inside setup, **don't add the "value" key**.

DO THIS
  const {
            loginUser
        } = **Login(email, password)**

INSTEAD OF
  const {
            loginUser
        } = **Login(email.value, password.value)**

**But to use the arguments inside of the composable function file, you must use the value key**

**demo-login.js**

DO THIS

  const user = await axios.post("/api/users", {
                email: **email.value,**
                password: **password.value**
            })

INSTEAD OF 

  const user = await axios.post("/api/users", {
                email: **email,**
                password: **password**
            })

That's it, guys! Leave any comments or questions below. Thanks for reading ☺️