Ionic7 vuejs loadingController

Hello Guys,

I am testing ionic7 vuejs, when working with fetch/api calls and using loadingController, I don’t find any official doc in for vue loadingController.

my code:

async function showLoader(
     cssClass = "loading-custom-class",
     message = "Please wait...",
     duration = 0,
     translucent = false,
     backdropDismiss = false,
     spinner: any,
     id: "login"
   ): Promise<void> {
     const loading = await loadingController.create({
       cssClass,
       message,
       translucent,
       backdropDismiss,
       spinner,
       duration,
       id,
       // keyboardClose: true
     });
     // Show loader
     console.log("show loader");
     return await loading.present();
   }
const filterNews = (subFilter, index) => {
      let resp = showLoader();
      selectedSubFilter.value = index;
      fetchArticles(subFilter.tags);
      resp.dismiss("login");
    };

I went through various articles but didn’t get the correct way of implementing loadingController.
Any hint will be helpful.
Thanks

The docs have a Vue example here.

But, I think you are just missing await when calling showLoader().

let resp = await showLoader();

Here’s my implementation that might be helpful:

Implementation (loading-component.ts)

import { loadingController } from '@ionic/vue'

interface Options {
    text?: string
    definedText?: 'Deleting' | 'Loading' | 'Refreshing' | 'Saving'
}

export class LoadingComponent {
    private options: Options
    private controller!: HTMLIonLoadingElement

    public constructor(options: Options) {
        this.options = options
    }

    public async initialize(): Promise<void> {
        this.controller = await loadingController.create({
            message: this.determineText(),
        })
    }

    public present(): void {
        this.controller.present()
    }

    public dismiss(): void {
        this.controller.dismiss()
    }

    public static async create(options: Options): Promise<LoadingComponent> {
        const loader = new LoadingComponent(options)
        await loader.initialize()

        return loader
    }

    private determineText(): string {
        if (this.options.definedText) {
            return `${this.options.definedText}&hellip;`
        }

        return this.options.text ?? ''
    }
}

Using

const loading = await LoadingComponent.create({ definedText: 'Deleting' })

loading.present()
// Do stuff
loading.dismiss()

Thanks @twestrick It makes perfect sense, but it seems like I’m still missing something, may be you can identify the issue in this code that prevents me using loadingController.


import {
  IonItem,
  IonLabel,
  IonList,
  IonButton,
  IonThumbnail,
  IonText,
  loadingController,
} from "@ionic/vue";
import { defineComponent, ref } from "vue";
import contentService from "../providers/contentService";
import { Splide, SplideSlide } from "@splidejs/vue-splide";
import "@splidejs/vue-splide/css";

import ListItem from "@/components/list/ListItem.vue";
import MyFavoriteTopBar from "@/components/frontpage/MyFavoriteTopBar.vue";

export default defineComponent({
  name: "FrontPageComponent",
  components: {
    Splide,
    SplideSlide,
    IonItem,
    IonLabel,
    IonList,
    IonButton,
    IonThumbnail,
    IonText,
    ListItem,
    MyFavoriteTopBar,
  },
  setup() {
    const { fetchArticles, contentList } = contentService();
    const selectedSubFilter = ref("latest");
    const subFilters = ref({
      ...
    });

    const options = ref({
      rewind: true,
      autoplay: true,
      perPage: 2,
      perMove: 2,
      gap: "0.3rem",
      arrows: false,
      pagination: false,
    });

    /* can't use async method in setup()
    const async filterNews */
    const filterNews = (subFilter: object, index: string) => {
      selectedSubFilter.value = index;
      let loading = await showLoader();
      fetchArticles(subFilter.tags);
      loading.dismiss();
    };

    async function showLoader(
      cssClass = "loading-custom-class",
      message = "Please wait...",
      duration = 0,
      translucent = false,
      backdropDismiss = false,
      spinner: any,
      id: "login"
    ): Promise<void> {
      const loading = await loadingController.create({
        cssClass,
        message,
        translucent,
        backdropDismiss,
        spinner,
        duration,
        id,
        // keyboardClose: true
      });
      // Show loader
      console.log("show loader");
      return await loading.present();
    }

    return {
      // Methods
      filterNews,
      contentList,

      // formatContentDate,
      options,
      subFilters,
      selectedSubFilter,
    };
  },
});
</script>
<template>
  <MyFavoriteTopBar></MyFavoriteTopBar>
  <div class="filters">
    <ion-button
      v-for="(subFilter, index) in subFilters"
      :key="subFilter"
      :color="selectedSubFilter == index ? 'primary' : 'light'"
      @click="filterNews(subFilter, index)"
    >
      {{ subFilter.title }}
    </ion-button>
  </div>
  <ion-list class="article-list">
    <ListItem
      v-for="data in contentList"
      :key="data.content.id"
      :data="{
        id: data.content.id,
        name: data.content.name,
        feature_name: data.article.feature_name,
        picture_url: data.article.picture_url,
      }"
    >
    </ListItem>
  </ion-list>
</template>

What is happening in fetchArticles? Do you need to await that too?