Accessing vue composable instance in function?

Advertisements

Lets say I have a simple vue composable function which I’d like to reuse many times throughout my app. In this case, it’s got one reactive property (products, an array containing a list of products), and one method "addProduct" which pushes a new element to the array.

export function useCart(){
    const products = ref([])

    const addProduct() =>{
        products.push({item: "Baseball Cap", quantity: 1})
    }

    return {
        products,
        addProduct
    }
}

That works fine. However, I’d like to pass the instance of the cart composable to each line, such that the line can access the parent "cart" via the property "cart".

I would expect the following to work. I believe "this" should reference the object (instance of cart) calling the function:

export function useCart(){
    const products = ref([])

    const addProduct() =>{
        //this should be the instance of the cart composable?
        products.push({item: "Baseball Cap", quantity: 1, cart: this})
    }

    return {
        products,
        addProduct
    }
}

However, when I test in the component consuming the composable, the value of "this" is undefined:

const testCart = useCart
testCart.addProduct()

Why is "this" undefined in this context, and how can I access the composable instance inside of the composable method?

>Solution :

If you do it right, then it works.

But you have to use functions() instead of lambdas, since lambdas have no context and this = window

const addProduct = function() {
    //this should be the instance of the cart composable?
    products.value.push({item: "Baseball Cap", quantity: 1, cart: this})
}

But I struggle to use the this context from the .cart property.

Like cart.products.value[0].cart.products. It just does not work.

I would suggest you to rethink the design. I would not do it that way.

Check the playground. Second time it’s window.

const { ref } = Vue;

const useCart = function() {
    const products = ref([])
    const addProduct1 = function() {
        //this should be the instance of the cart composable?
        products.value.push({item: "Baseball Cap", quantity: 1, cart: this})
    }
    const addProduct2 = () => {
        //this should be the instance of the cart composable?
        products.value.push({item: "Baseball Cap", quantity: 1, cart: this})
    }
    return {
        products,
        addProduct1,
        addProduct2
    }
}

const cart = useCart();
cart.addProduct1();
console.log(cart.products.value[0].cart)
cart.addProduct2();
console.log(cart.products.value[1].cart)
<script src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.prod.js"></script>

Leave a ReplyCancel reply