Utilize Vue 3 for setting up reactive fetching with asynchronous JSON handling

I recently upgraded to Vue 3 and I'm trying to populate a reactive object by fetching data from a JSON API.

Here's how my component looks. Surprisingly, I am not encountering any errors but the expected results are not showing up either.

<template>
  <div>
    {{ state.test.total }}
  </div>
</template>

<script>
import { reactive } from "vue";

export default {
  setup() {
    const state = reactive({
      test: null,
    });

    state.test = async () => {
      return await fetch("https://api.npms.io/v2/search?q=vue");
    };

    return {
      state,
    };
  },
};
</script>

The expectation was to display a number on the screen as per the total field in the JSON data.

Concerning state.test

When I tried outputting just state.test, this is what I got:

function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }

Do you have any suggestions on how to overcome this hurdle?

Answer №1

When you write:

a = async function test() {
}

You're setting a function to your state. However, if you write

a = (async function test() {
})();

You are still assigning a promise to a, not a value. To assign a value, you need to resolve the promise like this:

funcResult = await a;

The setup function is not appropriate for code that needs to run during the component's lifecycle. The setup function acts as a factory for your component and should always be synchronous (no async keyword) so Vue knows what to display while setup resolves. You can utilize hooks in the composition API instead:

import { onMounted, reactive } from "vue";

export default {
  setup() {
    const state = reactive({
      test: null,
    });

    onMounted(async () => {
      const response = await fetch("https://api.npms.io/v2/search?q=vue");
      state.test = await response.json();
    });

    return {
      state,
    };
  },
};

EDIT

Based on @boussadjra-brahim's answer, you can define an async setup function only if you wrap your component with <Suspense>. So you have these two options to choose from.

Answer №2

I believe that it's more advantageous to avoid delaying things.

Instance:

<template>
    <div>
        {{ result }}
    </div>
</template>


<script>
import { ref } from 'vue';

export default {
    setup() {
        const result = ref({});

        fetch('https://api.npms.io/v2/search?q=vue')
            .then(response => response.json())
            .then(data => result.value = data);

        return { result };
    },
};
</script>

Answer №3

To enhance the functionality, make sure to include the async keyword in the setup option and use await within the fetch function. Additionally, wrap the child component with a Suspense component inside the parent component:

<template>
    <div>
      {{ state.test.total }}
    </div>
</template>

<script>
import { reactive } from "vue";
export default {
  async setup() {
    const state = reactive({
      test: null,
    });

    try{
      state.test =  await fetch("https://api.npms.io/v2/search?q=vue");
     } catch (err) {
       console.error(err)
   }

    return {
      state,
    };
  },
};

Within the parent component:

<template>
  <Suspense>
    <Child/>
  </Suspense>
</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

Performing a function when text is clicked: Utilizing AngularJS

My goal is to trigger a specific controller method upon clicking on certain text. This function will then make remote calls to another server and handle the display of another div based on the response. Additionally, I need to pass parameters to this funct ...

Effective ways to replace an image using JavaScript

I am currently working on implementing a show/hide function, but I am encountering an issue with swapping the image (bootstrap class). The show-hide function is functioning properly; however, I am struggling to determine which class is currently displayed. ...

Is there a way to resolve the issue of Vue's v-html not supporting promises, etc.? It seems that all Vue binding values do not support promises

my project's code involves the formatter method, which might incorporate async functions and the use of async and await. However, when I implement them, the page does not render properly. Is there a solution to this issue? ...

Managing JavaScript events in the console

Running a server for a video game in node.js where the console communicates with clients via websockets. I have a function to spawn enemies from a MySQL database, but I am encountering an error that seems to be related to a jQuery script... I want the scr ...

Having issues with Next.js when trying to access elements using document.getElementById

Issue encountered: The value argument for the set operation failed due to an invalid key (__reactFiber$3ojngwn446u) in the property 'users.id.username.userN'. Keys must be non-empty strings and cannot contain ".", "#", "$", "/", "[", or "]". I r ...

How to extract information from a JavaScript object array in Node.js?

Currently, I am attempting to extract data from a JavaScript Object array by providing field names and then storing the data in an array. However, my current approach seems to be yielding incorrect results. Whenever I try to log the values stored in ' ...

What measures can be taken to safeguard my web app from unauthorized devices attempting to connect?

I am looking for a way to restrict access to a webapp so that only authorized users can connect from approved computers or mobile devices. If a user enters the correct username and password, access will be granted only if they are using a device approved b ...

Node.js process.exec() function allows you to asynchronously spawn a subprocess

After writing the code, I ran it and found that the terminal was unresponsive with no output, causing the program to be stuck. var util=require('util') var exec=require('child_process').exec; exec('iostat 5',function(err,stdo ...

What is the best way to retrieve the values of a select element from LEVEL 4 within the form submission of LEVEL 3?

To enhance readability, the intricate code has been abstracted. Within our Angular 2 project, we are working with a component called <top-component> (LEVEL 1): <top-component> </top-component> This component includes a template known a ...

Various concatenated and compressed JavaScript files across multiple HTML documents within a single application

In my express.js application, I have different routes such as /home and /dashboard. For example, on the home page, I include: jquery.js, underscore.js, somemodule1.js, somemodule2.js. On the dashboard, I include: jquery.js, underscore.js, somemodule3.js, ...

Executing a function by clicking on a DIV with the value of a textbox, instead of clicking directly on the textbox

Here is a function I have: $("#border-radius").click(function(){ var value = $("#border-radius").attr("value"); $("div.editable").click(function (e) { e.stopPropagation(); showUser(value, '2', this.id) $(this).css( ...

Encountering the issue: "Error: Unable to locate preset "env" in relation to the current directory"

Encountering the following error message Error: Couldn't find preset "env" relative to directory when trying to run my project using either npm run dev or npm run build I would greatly appreciate any assistance, as I have been struggling with this is ...

When using React.js with Leaflet, ensure that the useEffect hook is only run on Mount when in the

I have encountered an issue where I need to ensure that the useEffect Hook in React runs only once. This is mainly because I am initializing a leaflet.js map that should not be initialized more than once. However, anytime I make changes to the component&a ...

Error in Javascript chrome when trying to determine the length of an array

I am facing an unusual issue with the JavaScript console in Chrome. When I type the following code into the console: var numbers = new Array(["/php/.svn/tmp", "/php/.svn/props"]); it returns "undefined." This leads me to believe that 'numbers' ...

What is the purpose of incorporating .prototype within the function?

I came across John Resig's slideshow at http://ejohn.org/apps/learn/#78 I'm a bit confused about the necessity of using .prototype in the statement Me.prototype = new Person(); function Person(){} Person.prototype.getName = function(){ return ...

Unable to bind knockout dropdownlist data during an ajax request

Trying to connect a dropdownlist in knockout with MVC 4. Below is the code snippet: Action public JsonResult GetUserTypes() { using (QuestApplicationEntities db = new QuestApplicationEntities()) { var usertypes = (from ...

Transmitting information through socket.emit from the client to the server

I'm facing an issue while trying to send numeric data from the client to the server using socket.emit. The problem is that the server doesn't seem to be receiving any data, as only `null` gets logged or I might be doing something wrong in my appr ...

Switching Bootstrap Navbar Active State with JavaScript

I have encountered an issue with using the "active" class on my navbar navigation items in Bootstrap 4. When I click on the links, the active state does not switch as intended. I have tried incorporating JavaScript solutions from similar questions but have ...

Guidelines on Transferring Variables to a JavascriptExecutor Script

Currently, I am utilizing C# and Selenium to browse through a website and have come across an issue regarding passing variables into my JavaScriptExecutor command. When I attempt to do so using the code below: ((IJavaScriptExecutor)webdriver).ExecuteScript ...

The CSS transition fails to function correctly once a specific function is executed

When I hover over a div, the background color changes due to a transition effect. However, if I click on a button that triggers myFunction2 to change the background color of the div before hovering over it, the transition effect no longer works. functi ...