Accessing composable variables in Vue 3 without having to redefine refs from within a function

Currently, I am implementing a parent companyList component along with a reusable Table component and an useFetch composable in vue 3.2.

Prior to integrating the Table component, my code looked like this:

companyList

<script setup>
    import { computed } from 'vue';
    import useFetch from '@/composables/useFetch';
    import { formatEmail, formatPhone, formatEnterpriseNumber } from '@/utils/formatters';

    const { response, isFetching, error } = useFetch('get', '/companies');

    const companies = computed(() =>
        response.value?.companies?.map((company) => ({
            id: `#${company.id}`,
            name: `${company.legal_entity_type} ${company.business_name}`,
            enterprise_number: formatEnterpriseNumber(company.enterprise_number),
            email: formatEmail(company.email),
            phone: formatPhone(company.phone),
        }))
    );
</script>

Within the Table component that includes pagination, sorting, and search functionality, a watchEffect observes state changes and triggers an emit from the parent component, specifically getCompanies. Here's how it looks:

companyList

<script setup>
    const getCompanies = (search, sortKey, orderKey) => {
        const { response, isFetching, error } = useFetch('get', '/companies', {
            params: {
                keyword: search,
                sort_by: sortKey,
                order_by: orderKey,
            },
        });
    };

    const companies = computed(() =>
        response.value?.companies?.map((company) => ({
            id: `#${company.id}`,
            name: `${company.legal_entity_type} ${company.business_name}`,
            enterprise_number: formatEnterpriseNumber(company.enterprise_number),
            email: formatEmail(company.email),
            phone: formatPhone(company.phone),
        }))
    );
</script>

<template>
    <Spinner v-if="isFetching" size="medium" />
    <ErrorMessage v-else-if="error" showReload :description="error" />
    <NoDataMessage v-else-if="!companies || companies.length <= 0" />
    <div v-else>
        <Table :columns="tableColumns" :data="companies" @fetchData="getCompanies">
            <template v-slot:id="{ item }">
                <Badge>
                    {{ item.id }}
                </Badge>
            </template>
            <template v-slot:actions="{ item }">
                <router-link :to="{ name: 'clientDetails', params: { client_id: item.id } }" class="text-blue-500 lowercase"> {{ $tc('detail', 2) }} </router-link>
            </template>
        </Table>
    </div>
</template>

Question: I am looking for a way to extract the response, isFetching, and error values from the getCompanies function and utilize them inside the template tags without resorting to defining refs to retrieve them. Additionally, using different variable names makes the solution less optimal. Is there an alternative approach to the following workaround:

const local_response = ref(null);
const local_isFetching = ref(null);
const local_error = ref(null);

const getCompanies = (search, sortKey, orderKey) => {
    const { response, isFetching, error } = useFetch('get', '/companies', {
        params: {
            keyword: search,
            sort_by: sortKey,
            order_by: orderKey,
        },
    });

    local_response.value = response;
    local_isFetching.value = isFetching;
    local_error.value = error;
};

const companies = computed(() =>
    local_response.value?.companies?.map((company) => ({
        id: `#${company.id}`,
        name: `${company.legal_entity_type} ${company.business_name}`,
        enterprise_number: formatEnterpriseNumber(company.enterprise_number),
        email: formatEmail(company.email),
        phone: formatPhone(company.phone),
    }))
);

Answer №1

Delay the execution until you're ready with useFetch:

const {  go: fetchProducts, result, loading, errorMessage } =  useFetch('fetch', 
 '/products', {
    instant: false, // wait to execute until go is triggered
    details: {
        type: productType,
        category: productCategory,
        brand: productBrand,
    },
});

// fetchProducts, result, loading, and errorMessage will be accessible in the template 

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips to prevent encountering the "The response was not received before the message port closed" error while utilizing the await function in the listener

I'm currently in the process of developing a chrome extension using the node module "chrome-extension-async" and have encountered an issue with utilizing await within the background listener. In my setup, the content.js file sends a message to the ba ...

The system encountered an issue: "Property 'add' is not defined and cannot be read."

I'm facing a dilemma with my exercise. Despite the numerous inquiries regarding this problem, I haven't been able to find a solution. I am hopeful that you can provide some assistance! Below is the code snippet in question: let myDivs = docume ...

Understanding how to translate the content of email confirmation and password reset pages in Parse Server

Is there a way to translate the Email Confirmation and Password Reset pages in my project using Parse server? I have searched everywhere for a solution but haven't found one yet. While I did come across information about email templates, I couldn&apos ...

How can we utilize a loop to continuously sum up numbers until we reach a multiple of another number, let's say when the total is divisible by 4?

I am trying to create a function in JavaScript that will detect when a given number is not a multiple of 4. If the number is not a multiple of 4, I want to add numbers incrementally until it reaches the closest multiple of 4. Here’s what I have so far: ...

Instructions for activating column resizing in MUI DataGrid

Is there a way to enable column resizing for users in MUI DataGrid? It's enabled by default on XGrid, but I would like to enable it on Datagrid as well. Any assistance is appreciated. <DataGrid className={classes.table} ...

Error code 405: The POST method is not compatible with submitting multiple forms using JavaScript code simultaneously

Having multiple forms on a single page that are all submitted using the same JavaScript code presents some challenges. <form class="form" id="cancelchallenge1" method="POST" action="{{action('ChallengeController@cancelChallenge')}}"> <i ...

Using Vue CLI, incorporating sass modules can be made easier by adding include paths. Learn how to utilize include paths for

Embarking on a new project with Vue CLI for the first time. Opting for the Spectre CSS framework, installed via NPM. Trying to streamline imports by utilizing the includePaths option for a more efficient process. In essence, looking to reduce complexity ...

Ramda Transitioning to a Liberated Style of Programming

Unable to find a suitable resource for this particular issue. I apologize if this question has already been asked, but my attempts to locate the answer have proven fruitless (perhaps due to a lack of effective search methods). I've developed a functi ...

Implementing JavaScript functionality based on a specific body class

Is there a way to execute this script only on a specific page with a particular body class? For example, if the page has <body class="category-type-plp"> How can I target my script to work specifically for "category-type-plp"? plpSpaceRemove: fun ...

What is the method for shifting content as the window is resized to ensure it remains in its original position?

My page features a grid with three div elements. Each div is the size of the viewport, resulting in only one div being visible at a time, while the other two remain outside the view. This makes the grid three times larger than the viewport. When resizing ...

Incorporating a feature to leave comments in JSON data through AngularJS

Yesterday, I completed an AngularJS test that presented me with two tasks. One task involved displaying the data of a JSON file on a webpage in HTML form. I accessed the FreshlyPressed JSON via the link "" and effectively showcased the thumbnail, pos ...

How can I create a new PHP table using data from an existing table?

I have a table displayed on my website with the code snippet providedview the table image here Here is the code for generating this table: <?php $query = $db->query("SELECT * FROM bit_exchanges ORDER BY id DESC LIMIT 20"); if($query-> ...

Having trouble with flash messages in Node.js?

Could anyone shed some light on why the flash messages are not displaying properly in my situation? Here is how I'm attempting to utilize them: This snippet is from my app.js file: var express = require('express'); var app = express ...

The Material UI dialog box popped up against an unexpected gray backdrop

Currently, I am using Material UI in conjunction with React to create a dialog that appears when a button is tapped. This button is located within a table, which is displayed over a Paper component. The problem arises when I utilize the dialog with its def ...

Learn how to simultaneously play two audio files using the same identifier in JavaScript

I'm facing an issue with two audio files that have a progress bar and both have the same ID: <audio id="player" src="<?=base_url('mp3/'.$rec->file)?>"></audio> </p> ...

Unregistering an event with AngularJS

Exploring the functions of a controller named MyCtrl: class MyCtrl { constructor($scope, $rootScope, ...) { this.$scope = $scope; this.$rootScope = $rootScope; this.doThis = _debounce(this.resize.bind(this), 300); ... ...

When onSucess is called within a Vue view, the metadata parameter returns undefined, whereas it works properly inside a

In my Vue component for Plaid Link, there is a function/action in my Vuex store called onSuccess. This function is supposed to call my backend API to exchange the public token for an access token and send some data about the link to the backend. However, I ...

Getting the values of $scope variables from AngularJS in the controller to the view

I have a simple scope variable on my AngularJS Controller. It is assigned a specific endpoint value like this: $scope.isItAvailable = endpoint.IS_IT_AVAILABLE; How can I properly use it in my view (HTML) to conditionally show or hide an element using ng- ...

A step-by-step guide to creating adorable rounded corners in a DIV element

I'd like to create a stylish rounded corner div on the top-right and top-left edges. I attempted it with the following code: border-top-left-radius: 5em; border-top-right-radius: 5em; Desired look of the div: https://i.stack.imgur.com/EoSvSm.jpg A ...

Regular expressions can be used to extract specific attributes and inner content from a div element within a contentEditable container

Context I am currently developing a tagging system called @Name for my website. Successfully, I have managed to detect names upon keystroke and replace the content with the corresponding div class='tag' data-id='User-id'>Name</di ...