Using "useFetch" multiple times can cause Error Nuxt3 to occur

After successfully creating a vueJS component, I encountered an error when adding a second "useFetch" call in my <script setup> tag. The error message displayed was:

A composable that requires access to the Nuxt instance was called outside of a plugin, Nuxt hook, Nuxt middleware, or Vue setup function. This is probably not a Nuxt bug. Find out more at `https://nuxt.com/docs/guide/concepts/auto-imports#vue-and-nuxt-composables`.
    at Module.useNuxtApp (/Users/user/Code/Personal/universityCheckIn/node_modules/nuxt/dist/app/nuxt.js:216:13)
    at Module.useAsyncData (/Users/user/Code/Personal/universityCheckIn/node_modules/nuxt/dist/app/composables/asyncData.js:26:38)
    at Module.useFetch (/Users/user/Code/Personal/universityCheckIn/node_modules/nuxt/dist/app/composables/fetch.js:63:43)
    at checkIfCheckedIn (/Users/user/Code/Personal/universityCheckIn/pages/check-in.vue:51:50)
    at init (/Users/user/Code/Personal/universityCheckIn/pages/check-in.vue:75:30)

The relevant part of my <script setup> section looks like this:

<script setup>
  // General Values
  const alreadyCheckedIn = ref(false);
  const showModal = ref(false);
  const lecture = ref(null);

  // Modal Values
  const lectureName = ref("");
  const startTime = ref("");

  // Error handling
  const displayError = ref(false);
  const errorMessage = ref("Please fill in all fields.");

  // Fetch lecture data
  async function fetchLectureData() {
    const lectureDateObj = new Date();
    const lectureDateStr = lectureDateObj.toISOString().split("T")[0];
    const { data } = await useFetch("/api/lecture", {
      method: "GET",
      query: {
        lectureDate: lectureDateStr,
        groupId: 1, //TODO: get the group id from the user
      },
    });

    if (data.value.statusCode === 404) {
      return;
    }
    return data.value.body ? await JSON.parse(data.value.body) : null;
  }

  async function checkIfCheckedIn() {
    const lectureDateObj = new Date();
    const lectureDateStr = lectureDateObj.toISOString().split("T")[0];
    const { data } = await useFetch("/api/check-in", {
      method: "GET",
      query: {
        lectureDate: lectureDateStr,
        userId: 1, //TODO: get the user id from the user
        groupId: 1, //TODO: get the group id from the user
      },
    });

    if (data.value.statusCode === 404) {
      return false;
    }
    return true;
  }

  // Initialize lecture data
  async function init() {
    const lectureFromDB = await fetchLectureData();
    if (lectureFromDB) {
      lecture.value = lectureFromDB;
      lecture.value.start_time = new Date(
        lecture.value.start_time
      ).toLocaleTimeString("de-DE", { hour: "2-digit", minute: "2-digit" });
    }
    alreadyCheckedIn.value = await checkIfCheckedIn();
  }
  init();
.
.
.

Prior to adding the checkIfCheckedIn() function and encountering the error, the fetchLectureData() function was functioning properly. However, upon further investigation by removing fetchLectureData() and keeping only one "useFetch" call, the issue dissipated, indicating that the problem arises when having two simultaneous "useFetch" calls.

If using "useFetch" in this manner is not viable, how can I execute two independent API calls upon page load?

Answer №1

After digging through the documentation, I finally found the solution to my problem. It turns out that in order to use certain functionalities synchronously, such as calling a composable, you cannot use await before the call.

Since both of my operations were asynchronous and one was blocking the other, I encountered an error when using "await" before a composable. To overcome this issue, I decided to restructure my code and avoid calling one await before the other by utilizing Promise.all:

Promise.all([fetchLectureData(), checkIfCheckedIn()])
      .then(([lectureFromDB, checkedIn]) => {
        if (lectureFromDB) {
          lecture.value = lectureFromDB;
          lecture.value.start_time = new Date(
            lecture.value.start_time
          ).toLocaleTimeString("de-DE", { hour: "2-digit", minute: "2-digit" });
        }
        alreadyCheckedIn.value = checkedIn;
      })
      .catch((error) => {
        console.error(error);
      });

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

MenuIcon Component is experiencing difficulty being rendered

I am attempting to construct an IconMenu within the AppBar Component. My project is being developed using create-react-app. This is how my code appears: index.js import React from 'react'; import ReactDOM from 'react-dom'; import &a ...

Displaying nested arrays correctly

My latest endeavour involves constructing a data tree in Vue, utilizing components. Let's examine the provided data snippet: "data": [ { "id": 1, "name": "foo", "children": [ { "id": 2, "name": "bar", "children": [] } ...

The data point on jqPlot does not display in full

I've been working on creating a chart with jqPlot to display data for each hour. It's mostly going well, but there's an issue where the first and last data points are not showing correctly - part of the circle is getting cut off. Here' ...

Using Ajax.ActionLink to pass a parameter in JavaScript

When I call a controller in this manner: @Ajax.ActionLink("Clients", "ClientAccountsPartialView", new { entityCode = -1, taxNumber = -1, country = 1, ...

Ways to update the component's state externally

I'm new to Next.js (and React) and I'm attempting to update the state of a component from outside the component. Essentially, I am conditionally rendering HTML in the component and have a button inside the component that triggers a function to se ...

Retrieve the canvas coordinates for the images starting at lx and ending at rx on the x-axis, and

Currently, I am working on a project where I need to implement a drag and drop feature for an image within a PDF document. The goal is to retrieve the coordinates of the dragged image and use them later for document signing. The situation I am dealing wit ...

Make sure to confirm the input length and utilize bootstrap validation for error checking

I have a rather straightforward question. I am currently utilizing Bootstrap 4.6 and am looking to implement form validation for my input field. The requirement is to validate whether the input has a length of 5 characters or less, in which case it should ...

HtmlUnit: clicking on an anchor element does not result in the event being triggered

When I attempt to click on this specific link: <a id="table_statementlist_get_ib_table:0:ordernumber" class="OraLink" href="#" onclick="return _chain('disable_load_window();','submitForm(\'ib_trn_base_pas_statementlist_get&bsol ...

"Adding the Whats app share button underneath your Blogger post: A step-by-step guide

Can you help me with adding a Whats App share button below my post? Here is the CSS code on my website: .tl-postShare{text-align:right;} .tl-postShare ul{display:inline-block;} .tl-postShare ul li{margin:0;} .tl-tagnShare{position:relative;overflow:hidde ...

Step-by-step guide on displaying elements within an array of objects

Upon receiving an object from a website, I discovered that it includes an array of objects along with other parameters. When I use console.log(req.body.cart), the output is [ { title: 'iphone 6', cost: '650' } ], but I only require the ...

Problem with declaring Javascript objects

Exploring the world of OOP for the first time, encountering a small challenge: const panel = { image : imgs[24], proportion : this.image.height / this.image.width, height : this.image.height - (scale), width : height / proportion, ...

Is there a way to instantiate a new object within the same for loop without replacing the ones created in previous iterations?

My current issue with this exercise is that as I convert the first nested array into an object, the iteration continues to the next nested array and ends up overwriting the object I just created. I'm wondering how I can instruct my code to stop itera ...

What methods can I employ to utilize PHP or JS/HTML for posting to two separate URLs simultaneously?

Is it possible to submit a form from one button to two different locations? I am looking for a solution to achieve this. After clicking the submit button on a form, the form tag looks like this: <FORM ACTION="http:site.com/servlets/RequestServlet" met ...

Choose a specific parameter from a line using the body parser in Node.js

Upon receiving a post message, I am having trouble selecting a value from CSV data. Here is a sample of what I receive: { reader_name: '"xx-xx-xx-xx-xx-xx"', mac_address: '"name"', line_ending: '\n', field_delim: & ...

Navigating with Anchors, Styling and jQuery

Firstly: Apologies in advance for any language errors as English is not my native tongue. :) The Scenario Here's the deal: I'm attempting to create a single button that, when clicked by the user, automatically scrolls down to the next DIV. Each ...

Issue with Multiple File Upload Functionality in Dropzone.js + Laravel (Only allowing one file to be uploaded)

Looking for assistance in uploading multiple files using AJAX with Dropzone.js plugin. This is what I have implemented so far - HTML (view)- <div class="dropzone" id="add-slide-image"> </div> JS- Dropzone.autoDiscover = false; var myDropzo ...

Changing the z-index using createjs

Is there a way to ensure that the dragged item always stays on top when moved? How can I prevent it from getting dragged underneath another object? Can I specify which "sequenceNumbers" should be moved to the top of the sorting order? //++++++++ ...

Condensing CSS and Javascript using Java or Scala

I have a requirement to dynamically generate CSS/JavaScript for my project. After generating this code (most likely with PHP), I need to retrieve the string, minify it, and then save the minified file. I tried looking for a Java/Scala tool that can acco ...

Using Jquery to attach an event listener to an iframe

**I am currently utilizing a jQuery textselect plugin to trigger alerts based on the selected text anywhere on the page, and it is functioning well with code like this: $(document).ready(function() { $(document).bind('textselect', function( ...

What is the best way to output a variable that is returned by a function?

Here is a function I have: function findAddressViaGoogle(address){ var geocoder = new google.maps.Geocoder(); geocoder.geocode( { 'address': address }, function(results, status) { if (status == google.maps.GeocoderStatus.OK) { ...