The Vue data retrieved from an API using onMounted() is not initially showing up in the DOM. However, it magically appears after I make changes to the template

Hello and thank you to those taking the time to read this. I am new to Vue, so I may be overlooking something obvious here, but after being stuck for several days, I am reaching out for help.

In my SFC file, I have an onMounted function fetching data from an API (Spring Boot). The API call is successful as I can see it in the Network tab on Chrome, with the Response containing the necessary data.

Here is my AppLeague.vue file:

<template lang="">
    <div class="row">
        <div class="col-md-12">
            <h3>Leagues</h3>
        </div>
        <div class="col-md-12">
            <ul class="list-group">
                <li
                    v-for="(leagueItem, index) in leagues"
                    :key="index"
                    class="list-group-item"
                >
                    {{ index + 1 }}.{{ leagueItem.league_name }}
                    , Status:
                    {{ leagueItem.league_status }}, Code: {{ leagueItem.league_code }}
                </li>
            </ul>
        </div>
    </div>
</template>

<script setup lang="ts">
import { onMounted } from "vue";
import customAxios from "@/lib/customAxios";

interface League {
    league_id: number,
    league_name: string;
    league_code: string;
    league_status: string;
}

let leagues: League[];

onMounted(async () => {
    await customAxios
        .get<League[]>(`account/leagues`, {
            withCredentials: true,
    })
    .then((response) => {
        leagues = response.data;
    });
});
</script>

My unique axios module:

import axios from "axios";

export const customAxios = axios.create({
    baseURL: "http://localhost:8080/api/",
});

customAxios.interceptors.response.use(
    (response) => response,
    (error) => {
        if (error.response.status === 401) {
            window.location.href = '/';
        }
        if (error.response) {
            alert(error.response.data.message);
        }
    }
);

export default customAxios;

In Google Chrome's Network tab, I can observe the HTTP 200 code and the Response:

[{"league_id":1,"league_status":"created","league_name":"Test League","league_code":"Test League Code"}]

However, when I view the rendered page, the values are not displayed initially. Instead, they appear only after I make a minor change within VSCode and save, triggering a refresh of the page where the values then appear correctly:

If you're curious, take a look at how the page looks after altering the DOM in VSCode here.

I'm seeking a solution to ensure the values are displayed upon page load without needing to manipulate the DOM. It seems that the initial empty values of let leagues: League[]; are causing this issue, requiring a DOM alteration to display the fetched data. Any suggestions on how to force the DOM to show the fetched values directly would be greatly appreciated.

I have scoured for examples involving Vue3 and ., but have come up short. Thank you!

Answer №1

According to @dan-obregon, the crucial aspect of Vue that you overlooked is its reactivity. Dan's response falls short as simply assigning the array to the reactive object won't work. In this scenario, it would be more appropriate to utilize ref:

<script setup lang="ts">
import { Ref, ref, onMounted } from "vue";
import customAxios from "@/lib/customAxios";

interface League {
    league_id: number,
    league_name: string;
    league_code: string;
    league_status: string;
}

const leagues: Ref<Array<League>> = ref([]);

onMounted(async () => {
    await customAxios
        .get<League[]>(`account/leagues`, {
            withCredentials: true,
    })
    .then((response) => {
        leagues.value = response.data;
    });
});
</script>

Answer №2

It might be beneficial to wait for the leagues value before proceeding. It's possible that you're encountering an error because the component is failing to load some values from your leagues property that haven't been fetched yet. When you save in VSCode, the component has already mounted and the leagues data has been retrieved, hence no error occurs.

One solution could be:

Add a conditional v-if statement within your component. If your axios response returns a non-empty list, then bind your data. For example, at line 6:

<template lang="">
    <div class="row">
        <div class="col-md-12">
            <h3>Leagues</h3>
        </div>
        <div v-if="leagues.length > 0" class="col-md-12">
            <ul class="list-group">
                <li
                    v-for="(leagueItem, index) in leagues"
                    :key="index"
                    class="list-group-item"
                >
                    {{ index + 1 }}.{{ leagueItem.league_name }}
                    , Status:
                    {{ leagueItem.league_status }}, Code: {{ leagueItem.league_code }}
                </li>
            </ul>
        </div>
    </div>
</template>

Answer №3

It appears that there may be an issue related to reactivity in this context.

If you are unfamiliar with reactivity, here are some helpful resources:

  • VueJS Reactivity (official documentation)
  • ref vs reactive (explained with examples for better understanding)
  • You can also search for 'vue ref reactive' to explore additional information on this topic

My suggestion would be to modify the way leagues are declared as follows:

import {reactive} from 'vue'
...
const league = reactive<Leagues[]>([])

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

Error: Conversion of "2018-01-01-12:12:12:123456" to a date is not possible for the 'DatePipe' filter

<td>{{suite.testSuiteAttributes && suite.testSuiteAttributes.modifiedTimestamp | date: 'yyyy-MM-dd' }} </td> I am trying to display the date in the "05-Feb-2018 11:00:00 PM CST" CST format, but I keep getting an ...

Angular is unable to modify the value of 'name' since it is either a constant or a property that cannot be modified

I am encountering an error that says "Cannot assign to 'name' because it is a constant or a read-only property" when trying to send data to the API. Does anyone know how I can solve this issue? Thank you. onSubmit() { const name = this.backU ...

Updating tooltip text for checkbox dynamically in Angular 6

Can anyone help me with this code? I am trying to display different text in a tooltip based on whether a checkbox is active or not. For example, I want it to show "active" when the checkbox is active and "disactive" when it's inactive. Any suggestions ...

When trying to retrieve a value from a custom render function in React with TypeScript, an error occurs indicating that the value is not assignable to type 'ReactNode'

Recently, I attempted to develop a versatile swiper component using Next.js 13 (App Router) v13.4.12 along with TypeScript. However, I encountered an issue when trying to access data from the component props, which involves a custom function for rendering ...

The assignment of Type Observable<Observable<any[]>> to Observable<any[]> is not valid

Working on implementing autocomplete using data from a database service: @Injectable() export class SchoolService { constructor(private db: AngularFirestore) { } getSchools(): Observable<School[]> { return this.db.collection<School> ...

Struggle with typescript integration with emotion and styled components

Issue Description: I encountered an issue while working with typescript and emotion/styled libraries. When attempting to specify the type of the parent component that wraps a styled component, I faced difficulties. The scenario involves a parent componen ...

Ensuring that environment variables are properly set is essential for effective error handling

I am currently integrating my NodeJS and Typescript App to create new config files that utilize .env variables. If a specific variable is not set, I want to trigger an error. After setting up my config file, I encountered some errors; however, I am unsure ...

Angular 11 - Error: The 'fetch' method could not be executed on the 'Window' object due to an illegal invocation

I have encountered an issue with a dependency in my current project. This particular dependency relies on isomorphic-unfetch for its functionality. Strangely, I am able to run isomorphic-unfetch without any problems within Angular 11. However, when I inclu ...

Leveraging CDK Context Variables in C# Lambda Initialization Code

I have a .NET Lambda function written in C# that is implemented as a .NET Minimal API according to the guidance provided here. To define AWS resources, I am utilizing CDK (TypeScript). Within my build pipeline, there is shell scripting involved to supply ...

Encountering Vue CLI issues during deployment of Vue application using Docker

I've been working on a VUE app locally and now I'm attempting to deploy it to a remote server for testing. My development machine is running Arch with Docker 20.10.17 The VUE app uses the following Dev.Dockerfile for building: FROM node:lts-alp ...

Using @RequestBody with a Map<String, String>[] in Spring Boot results in a collection of blank elements

My client side application is built with Angular. I am attempting to send a List of Map<String, String> to a Spring Boot REST API, but it seems to be getting serialized as a List of empty items. I have also tried using an array Map<String, String& ...

Encountering issues with HTML loading interpolation before constructor in TypeScript

I am currently working on a project using Angular 6 and encountering some challenges. Here is the issue at hand: I am facing an error in the HTML Console, which occurs after reloading the page. The error message indicates that the variable "atual" is unde ...

Issue occurred while trying to set the value from an API call response in the componentDidMount lifecycle method

There is a boolean variable disableButton: boolean; that needs to be set based on the response received from this API call: async getDocStatus(policy: string): Promise<boolean> { return await ApiService.getData(this.apiUrl + policy + this.myEndpo ...

Finding it challenging to adapt an AngularJs component-based modal to TypeScript

When creating an AngularJS component in JavaScript and displaying it as a modal using ui-bootstrap, you need to pass bindings that the modal instance can use for dismissing or closing itself: app.component("fringeEdit", { controller: "FringeEditCont ...

Unable to update the color of material icon using document.getElementById(item) method

if (document.getElementById(item).style.color == "grey") { document.getElementById(item).style.color = "red"; } <i class="material-icons" [ngStyle]="post.isLiked != null ? {'color': 'red'}: {'color': 'grey'}" id ...

Troubleshooting form submission issues in Angular 4

I am encountering a few issues with my search form. It is supposed to function as a search tool with one input field and one button. However, something seems amiss. I am utilizing an API that returns values based on the string inputted. When an empty value ...

When using Typescript, I am encountering an issue where declared modules in my declaration file, specifically those with the file

One of the declarations in my ./src/types.d.ts file includes various modules: /// <reference types="@emotion/react/types/css-prop" /> import '@emotion/react'; import { PureComponent, SVGProps } from 'react'; declare mod ...

What are the steps to troubleshoot an unexpected 302 redirect caused by an Ajax request?

I'm attempting to retrieve data from a database using this ajax request: axios.get('/about-info') web.php: Route::get('/about-info', [CMSController::class, 'aboutInfo']); CMSController.php: public function aboutInfo() { ...

Pagination in PrimeNG datatable with checkbox selection

I am currently working on incorporating a data table layout with pagination that includes checkbox selection for the data. I have encountered an issue where I can select data on one page, but when I navigate to another page and select different data, the s ...

How can I extract a value from an object that is readonly, using a formatted string as the key?

I encountered a situation where I have code resembling the following snippet. It involves an object called errorMessages and multiple fields. Each field corresponds to various error messages in the errorMessages object, but using a formatted string to retr ...