How can I create reactivity for this hook in Vue 3?

So here's the deal, I have this hook code snippet that goes like this:

export const useOpeningHours = (
  flight: Ref<FlightOption | null>,
  identifier: string,
  isEnabled?: boolean
) => {
  if (!flight.value) {
    return {
      show: false,
      gate: "",
    };
  }
}

const flight = ref<FlightOption | null>(null);

const { show: showOpeningHours } = useOpeningHours(
  flight,
  props.identifier,
  true
);

So my expectation was that since I'm using Ref<FlightOption | null>, the hook would automatically 'refresh' when the flight changes. But guess what? It's not happening. Any ideas on how to make sure the hook stays reactive in this scenario?

Answer №1

Given that you mentioned this as a simplified scenario, I will approach it as a more complex issue with three methods.

Utilize ComputedRef

For further details, refer to: https://vuejs.org/guide/essentials/computed.html#basic-example

export const applyOpeningHours = (
  flight: Ref<FlightOption | null>,
  identifier: string,
  isEnabled?: boolean
) => {
    return {
      show: computed(() => {
        if (flight.value) return false
        return true
      }),
      gate: computed(() => {...}),
    }
}

This provides show and gate as a ComputerRef, which is akin to show.value

Using @vueuse/core can streamline the process

export const applyOpeningHours = (
  flight: Ref<FlightOption | null>,
  identifier: string,
  isEnabled?: boolean
) => {
  return toReactive(computed(() => {
    if (!flight.value) {
      return {
        show: false,
        gate: "",
      };
    }

    return {
      show: ...,
      gate: ...
    } 
  }))
}


const flight = ref<FlightOption | null>(null);

const { show: showOpeningHours } = toRefs(applyOpeningHours(
  flight,
  props.identifier,
  true
));

Employ Reactive

export const applyOpeningHours = (
  flight: Ref<FlightOption | null>,
  identifier: string,
  isEnabled?: boolean
) => {
  const result = reactive({ <default value> })

  watchEffect(() => { // or watch, watchPostEffect, watchSyncEffect
    if (!flight.value) {
      result.show = false
      result.gate = ""
    }
    ...
  })

  return result
}


const flight = ref<FlightOption | null>(null);

const { show: showOpeningHours } = toRefs(applyOpeningHours(
  flight,
  props.identifier,
  true
));

Utilize Ref

export const applyOpeningHours = (
  flight: Ref<FlightOption | null>,
  identifier: string,
  isEnabled?: boolean
) => {
  const show = ref(false)
  const gate = ref("")

  watch(flight, flight => { // or watchEffect
    if (!flight) {
      show.value = false
      gate.value = ""
    }

    ...
  }, { immediate: true })

  return { show, gate }
}

Answer №2

To enhance your coding skills, try implementing a computed property in the following manner:

export const useFlightDetails = (flight: Ref<FlightOption | null>, identifier: string, isEnabled?: boolean) => {
  const details = computed(() => {
    if (!flight.value) {
      return {
        display: false,
        gate: "",
      };
    } else {
      return {
        display: true,
        gate: "GATE 1",
      };
    }
  });

    return {
        details
    };
};

Then, utilize it in your code like this:

const { details } = toRefs(useFlightDetails(
  flight,
  props.identifier,
  true
));

// Access the details using `details.value.display` or `details.value.gate`

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

Is it acceptable to incorporate Node.js modules for utilization in Next.js?

Here's a funny question for you. I am trying to generate UUID in my Next.js project without adding any unnecessary packages. So, I decided to import crypto in my component like this: import crypto from 'crypto'; After importing it, I used i ...

Tips for positioning two elements side by side on a small screen using the Bootstrap framework

Greetings! As a beginner, I must apologize for the lack of finesse in my code. Currently, I am facing an issue with the positioning of my name (Tristen Roth) and the navbar-toggler-icon on xs viewports. They are appearing on separate lines vertically, lea ...

React Router's nested route causes a full page reload when navigating

I have been working on setting up nested routing in React Router and here is my code: import React from 'react'; import DefaultSwitch from './components/DefaultSwitch/DefaultSwitch'; import './scss/App.scss'; const App = () ...

Using knockout to data bind a function to an onclick event that takes in multiple parameters

I've scoured the internet and experimented with various methods, but I'm encountering an issue where the click function intermittently fails to fire. Below is my HTML code snippet: <input type="radio" data-bind="checked:a, checkedValue: 0 ...

Iterating through a jQuery function to increment value

I have encountered an issue while trying to calculate the total value from an array of form fields. The problem lies in how the final value is being calculated on Keyup; it seems that only the last inputted value is being added instead of considering all t ...

What is the method for specifying a null value in Typescript?

I'm curious if this code snippet is accurate, or if there's a better way to define it. Is there an alternative to using error!? I'm unsure of its meaning and would appreciate clarification. ...

Exploring Azure: Obtain a comprehensive list of application settings from a deployed Node.js web application

After successfully deploying a NodeJs app to a Linux Azure AppService, I am now aiming to retrieve the server settings of this particular app-service. By enabling managed Identity for the AppService under the 'Identity' tab, I attempted to achiev ...

Validating checkboxes using HTML5

When it comes to HTML5 form validation, there are some limitations. For instance, if you have multiple groups of checkboxes and at least one checkbox in each group needs to be checked, the built-in validation may fall short. This is where I encountered an ...

experiencing unexpected outcomes while testing composable functions with fetch API

There is a composable function called useFetchData used to retrieve data: export const useFetchData = (q?: string) => { const data: Ref<Data | undefined> = ref(); const error: Ref<Error | undefined> = ref(); const isLoading = ref(true) ...

jQuery - patience is required until all elements have completely faded away

I am facing a unique challenge: I need to trigger an action after two specific elements have been faded out simultaneously. The code snippet for this task is as follows: $("#publish-left, #publish-right, #print-run").fadeOut(function(){ //do something ...

Utilize mapping function to merge arrays

Currently facing an issue with no clear solution in sight. When making API calls via a map, I am able to successfully log all results individually. However, my challenge lies in combining these results into a single array. var alpha = ['a', &apo ...

What might be causing my mongoose query to take so long? (~30 seconds)

I've encountered a problem with a route in my application. This specific route is supposed to fetch an array of offers that a user has created on the app by providing the user's id. Initially, when the user has only a few offers, the query execut ...

Install the npm package if there have been modifications to the package.json file

In short: Can we make npm install run automatically before executing any npm script if the package.json file has been modified? Situation Summary Imagine you switch to a branch that has updated the package.json file. You try running npm run my-script, bu ...

Warning: Using synchronous XMLHttpRequest on the main thread is no longer recommended as it can negatively impact the user's experience

I encountered an issue with my project while attempting an Ajax request [Warning] Using synchronous XMLHttpRequest on the main thread is now considered deprecated due to its negative impact on user experience. function retrieveReviews() { var reviewsD ...

Having trouble implementing the center edge effect in this CSS design

Looking for help with CSS to center the edges of a family tree design. Has anyone experience in working on styling family trees? *, *:before, *:after { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } .tree { ...

AngularJS: Customizable URL Prefix for Dynamic Routing

I am facing a challenge with my large Angular app that is currently accessible through the following URL: http://myangularapp.com/app/index.html#/ In order to support multiple users, I need to dynamically inject a name into the URL that I will be sharing ...

Addressing the Cross Domain Issue when Implementing DHIS 2 API with jQuery

Today, I spent hours trying to authenticate my javascript application with the DHIS 2 API using Jquery. According to the API documentation (https://www.dhis2.org/doc/snapshot/en/user/html/ch32s02.html), base 64 authentication is required. However, my attem ...

Tips for customizing table cell styling in editable cells with React material table

My code utilizes a material table with editable cells. However, I am encountering a strange style issue when I edit a cell in the table. Please refer to the image below. Can anyone suggest a solution to fix this problem? https://i.sstatic.net/Miiov.png ...

Display a loading dialog for several asynchronous requests being made via AJAX

When making two asynchronous ajax calls, a loading dialog box is displayed for each call using the code below: jQuery('#msg_writter').show(); After a successful request, the loading dialog is hidden with the following code: jQuery('#msg_w ...

Updates in dropdown events when options data has been modified

Hey there, I'm wondering about dropdown events. Let's say I have two dropdowns. When a selection is made in the first dropdown, all options in the second dropdown are replaced with new ones. For example, let's say the first dropdown has thes ...