Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

$apollo.loading is not working in multiple components #988

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
sonphnt opened this issue May 27, 2020 · 8 comments
Closed

$apollo.loading is not working in multiple components #988

sonphnt opened this issue May 27, 2020 · 8 comments

Comments

@sonphnt
Copy link

sonphnt commented May 27, 2020

Describe the bug
I have 2 components, one global component in the top right corner with spinner, and product component when users navigate to "/products".
In the product component, I have a call to graphql with apollo and $apollo.loading is working fine. I can see my loading bar work in this component.

But in global component, my spinner never shows with $apollo.loading.
<div v-if="$apollo.loading"><span class="spinner"></span></div>

I want my spinner in the top right corner showing when there are any queries to graphql server.

Is this a bug or I missed some configuration?
Thanks

Versions
vue: 2.6.11
vue-apollo: 3.0.3
apollo-client: 2.6.8

@ev3rest
Copy link

ev3rest commented Aug 21, 2020

This issue has been present in apollo for almost 3 years now. See #1314
I've been battling with this all day today and still can't figure it out

@vojtapol
Copy link

vojtapol commented Dec 4, 2020

I am still seeing this issue.

@nessor
Copy link

nessor commented Feb 20, 2021

Jep. Same here.

@toddpadwick
Copy link

Did anyone figure out a solution for this?
I have a similar requirement - I have a global loading indicator in the top right of my page, and I want it to display whenever any $apollo query is loading in any component. I could set up a vuex event but this would be seriously tedious to apply to every single $apollo query. I would have thought $apollo.loading would work but it always shows false.

@Akryum
Copy link
Member

Akryum commented Nov 28, 2021

This is expected behavior: $apollo.loading is the loading state for the current component. If you need a global loading indicator, use the watchLoading option of the VueApollo constructor as described in the docs:

const apolloProvider = new VueApollo({
  // Watch loading state for all queries
  // See 'Smart Query > options > watchLoading' for detail
  watchLoading (isLoading, countModifier) {
    loading += countModifier
    console.log('Global loading', loading, countModifier)
  },
})

@Akryum Akryum closed this as completed Nov 28, 2021
@toddpadwick
Copy link

@Akryum thanks so much for clarifying. I've got the loading indicator logged in the console now. What i can't work out now from the docs is how to access that loading state in any template?
Would i need to manually set up a value in the store from that watchloading config? or is there something already accessible from the $apollo object?

@Akryum
Copy link
Member

Akryum commented Nov 29, 2021

The implementation is left to you. You can for example use Vue.observable() to create a small reactive object that you can import in your components or in a global mixin.

const apolloState = Vue.observable({
  loading: 0,
})

Vue.mixin({
  computed: {
    $apolloGlobalLoading () { return apolloState.loading > 0 }
  }
})

const apolloProvider = new VueApollo({
  // Watch loading state for all queries
  // See 'Smart Query > options > watchLoading' for detail
  watchLoading (isLoading, countModifier) {
    apolloState.loading += countModifier
    console.log('Global loading', loading, countModifier)
  },
})
<template>
  <div v-if="$apolloGlobalLoading">Loading some query...</div>
</template>

@toddpadwick
Copy link

toddpadwick commented Nov 29, 2021

Fantastic that worked @Akryum .
For anyone else using Nuxt, first install the nuxt-community/observable-module.

Then in nuxt.config.js:

  modules: [
    '@nuxtjs/apollo',
    '@nuxtjs/observable'
  ],

  apollo: {
    includeNodeModules: true,
    watchLoading: '@/apollo/loadingHandler.js'
  },

@/apollo/loadingHandler.js:

export default (isLoading, countModifier, nuxtContext) => {
  isLoading += countModifier
  nuxtContext.$state.loading += countModifier;
}

/state.js

export default() => ({
	loading: 0,
})

then in your templates you can use $state.loading anywhere such as:

<loading-icon :is-loading="$state.loading"></loading-icon>

@vuejs vuejs locked and limited conversation to collaborators Nov 29, 2021

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Projects
None yet
Development

No branches or pull requests

6 participants