Vue.js dynamic components - render components dynamically after data has been successfully fetched within the component

I've been working on implementing dynamic components in Vue.js, but I'm having trouble figuring out how to display the component only after it has fetched its data. Until then, it should show the previous component.

Here's the scenario: When the page initially loads, it displays the Home component. Then, when I click on "Show posts", nothing should happen until the Posts component has successfully fetched its posts. Only then should the Posts component be displayed. I don't want any loading indicators to appear.

I could fetch the posts in my Home component, but I believe that responsibility should lie with the Posts component. Additionally, if there are many components, I prefer for each one to handle fetching its own data. Is this achievable?

home.js

import Home from './home.js'
import Posts from './posts.js'

export default {
    template: `
        <div>
            <a @click="showPosts">Show posts</a>
            <component :is="currentComponent" />
        </div>
    `,

    methods:
    {
        showPosts()
        {
            // Display Posts component ONLY after it has fetched its data... not immediately...
            this.currentComponent = Posts
        }
    },

    data:
    {
        currentComponent: Home
    },
}

posts.js

export default {
    template: `
        <div>
            <div v-for="post in posts">{{ post.body }}</div>
        </div>
    `,

    data:
    {
        posts: [],
    },

    created()
    {
        axios.get('/posts').then(({ data } => {
            this.posts = data
        })
    },
}

Answer №1

To effectively utilize the async created hook, pair it with a conditional v-if statement.

This means encapsulating your template within a v-if

template: '<div v-if="dataloaded">This is component xlr</div>

Within the async created function, load your data and switch the flag to true once processing is complete

  async created() {
  await loadData(3000);
  this.dataloaded = true;},

For a live example, check out this demo: https://jsfiddle.net/Postlagerkarte/yomb5qv6/

Answer №2

To ensure that the posts component is only displayed after data has been fetched, the best approach is to fetch the data within the parent component. By decoupling the fetching process from the component itself, you can create a more efficient and reusable code structure. Typically, this involves utilizing an apiService to handle the data fetching, while the Posts component focuses solely on presenting the data.

Below is an example of how your component could be structured:

home.js

import Home from './home.js'
import Posts from './posts.js'
import apiService from '../services/apiService.js'

export default {
    template: `
        <div>
            <a @click="showPosts">Show posts</a>
            <component :posts="posts" :is="currentComponent" />
        </div>
    `,

    methods:
    {
        showPosts()
        {
            apiService.fetchPosts().then((response) => {
                this.posts = response.data.posts
                this.currentComponent = Posts
            });
        }
    },

    data:
    {
        posts: []
        currentComponent: Home
    },
}

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

One common issue that arises is the failure of a Javascript function to execute when trying to display a div that is initially hidden using the CSS

I have a div on my website that is initially hidden using this css rule: .menu-popup{ display:none; border:1px solid #FFF; padding:8px; width:100%; height:100vh; position:fixed; top:60px; overflow:hidden; } When I click a ...

Manipulating data in a deeply nested field of an embedded document using Mongoose, MongoDB, and Express

I have been pondering whether it is feasible to input data into the comments field of my "TopicSchema": var mongoose = require('mongoose'); var TopicSchema = new mongoose.Schema({ username: String, topic: String, des ...

"Ensure div remains at the bottom of the page even while

In order to implement a feature where the menu sticks to the top when scrolling down, you can use the following JS code. You can view a live example of this functionality on this Plunker by widening the preview window to see the columns side by side. wi ...

A guide to creating a synchronous AJAX call using vanilla JavaScript

I am trying to make multiple AJAX calls in a loop using the code below. for (var i = 0; i < 5; i++) { console.log(i); ajax_DatabaseAccessor.query("CheckInt", i, loadQuery); function loadQuery(data) { alert(DWRUtil.toDescriptiveString ...

What is the most secure and accurate method for altering an object's state variable in React?

Behold, the code below has been tried and tested, effectively updating the state variable of the object: import { useState } from 'react' import './App.css'; function App() { const [config, setConfig] = useState({ status: & ...

Creating an HTML string from an array in JavaScript

Hi there, I'm in need of some assistance with a JavaScript task. Can anyone help? I'm looking to create a JavaScript function that can take an array and return the corresponding HTML string. For example: [tagName, child1, child2, ...] • The ...

Exporting a JavaScript chart to an Excel file using Highcharts

Trying to export a JavaScript chart (HighCharts) into an Excel file has been challenging. The chart, rendered in a div, does not carry over the HTML and CSS formatting that the JavaScript generates, resulting in plain text without style. I have attempted ...

Logging into a website using Ajax technology

Check out this screenshot of the console.As a novice in json and Ajax, I am attempting to create a login functionality for my website. However, I am encountering issues and can't figure out why it isn't working. login-register.js function login ...

Always keep your phone in landscape orientation for optimal website viewing

Currently, I am facing an issue with my website where it functions perfectly on mobile devices in landscape orientation but elements get distorted when viewed in portrait mode. Is there a method to ensure that the website is always displayed in landscape ...

Retrieving Data from a Promise - { AsyncStorage } React-Native

Currently, I am grappling with figuring out how to retrieve the outcome of a promise. My journey led me to delve into the React Native documentation on AsyncStorage available here: https://facebook.github.io/react-native/docs/asyncstorage I decided to uti ...

Send the loop index as a parameter to a function within the onclick attribute of an HTML <input> element using vue.js

My goal was to develop a basic to-do list using vue.js to familiarize myself with it. Now, I've successfully added a remove button next to each item. To achieve this, I included a remove() function in JavaScript with a id parameter, which corresponds ...

Can you explain the purpose of the state object that is passed to history.pushState? What role does it play in

Can you explain the purpose of the stateObj parameter in the function history.pushState? For instance, when calling the function history.pushState(stateObj, title, url). ...

Error: Unable to locate the module: Vue-Picture-BD-Marker

After successfully building my Vue project on my personal MacBook and running npm build without any issues, I encountered a problem when trying to deploy it on my CentOS server using Jenkins. The build failed with the following log: ERROR in ./node_modules ...

Running into the error message 'TypeError: Cannot invoke a class as a function' while utilizing Ziggy for Vue within Laravel

I have been searching endlessly for a solution to my issue without any luck. Here are the steps I have taken: \\Webpack.mix.js const mix = require('laravel-mix'); const path = require('path'); mix.webpackConfig({ resolve: ...

MathJax only functions properly on Firefox Browser; for all other browsers, it fails to work as intended

I have integrated MathJax into a website that I designed. Everything works perfectly fine on Firefox, but there seems to be an issue with MathJax input when I try to open the site on Opera, for example. Here is the code snippet that is causing problems on ...

The URI entered is not valid: The parsing of the hostname failed. Electron Builder

Having an issue while trying to build an electron app using squirrel, even though the iconUrl is valid. Here is my package.json configuration: "squirrelWindows": { "iconUrl": "http://95.85.39.111:5005/skylog.ico" }, Error message received: An unhand ...

Formatting dates with a DIV element

<div> <strong>Date: </strong> ${dateInUtc} </div> The timestamp (2021-12-09T15:43:29+01:00) in UTC format needs to be reformatted as 2021-12-09 - 15:43:29. Is there a way to achieve this without relying on ext ...

JavaScript nested filtering functions

In my code, I have an array named restaurant_items. This array consists of objects that represent various items from a restaurant. Each object contains another array called in_menu, which also consists of objects. I am looking to filter out the restaurant ...

Converting HTML to a Text String (not for display) using Angular

When it comes to displaying HTML in Angular, there are numerous approaches available. For example, using $sce.trustAsHtml(myHtmlVariable) is one way to achieve this. However, I am interested in creating something like the following: myStringVariable = s ...

What is the recommended method in React for dynamically adding elements to the DOM when a user clicks?

Is there a way to dynamically add "<li>" element to the box element when clicking the "innerButton", without having to specify the ID of any elements so that multiple boxes can be added as needed? export default class App extends Component { ...