How to use the loading property in a watchQuery when using the Apollo client for GraphQl
Asked Answered
S

3

15

So when i get the response from my query, i can see there is a loading property. But i don't really get why they would pass it along. Because when you get the response it means that the loading is finished, hence the loading will always be false.

Is there a way that i can use this loading property so that i can for example make a loading icon appear when the call is still loading?

I have the following code in an Angular 2 environment:

public apolloQuery = gql`
    query {
        apolloQuery 
    }`;

const sub = this.apollo.watchQuery<QueryResponse>({
    query: this.apolloQuery 
}).subscribe(data => {
    console.log(data);
    sub.unsubscribe();
});

And the log from the data object contains the loading property i was talking about, which is always false.

I know i can make my own boolean property and check this way, but i was just wondering if i could use the built-in loading property that Apollo provides?

Saturniid answered 18/5, 2018 at 9:56 Comment(0)
W
4

Your subscription has the loading parameter:

import { Component, OnInit } from '@angular/core';
import { Apollo } from 'apollo-angular';
import gql from 'graphql-tag';

// We use the gql tag to parse our query string into a query document
const CurrentUserForProfile = gql`
  query CurrentUserForProfile {
    currentUser {
  login
  avatar_url
}
  }
`;

@Component({ ... })
class ProfileComponent implements OnInit, OnDestroy {
  loading: boolean;
  currentUser: any;

  private querySubscription: Subscription;

  constructor(private apollo: Apollo) {}

  ngOnInit() {
    this.querySubscription = this.apollo.watchQuery<any>({
      query: CurrentUserForProfile
    })
      .valueChanges
      .subscribe(({ data, loading }) => {
        this.loading = loading;
        this.currentUser = data.currentUser;
      });
  }

  ngOnDestroy() {
    this.querySubscription.unsubscribe();
  }
}

https://www.apollographql.com/docs/angular/basics/queries.html

Wordless answered 24/5, 2018 at 14:5 Comment(5)
I understand that, but what use does it have and more importantly how can i use it? I cant see the importance of it because i can do it myself much easier: When making a call i set a boolean 'loading' to true, when i receive the call i set it back to false. The boolean parameter provided bu GraphQL is only available to me when the call is already done, right?Saturniid
The watchQuery method returns a QueryRef object which has the valueChanges property that is an Observable. We can see that the result object contains loading, a Boolean indicating if the query is "in-flight.": github.com/apollographql/apollo-angular/blob/master/docs/source/…Kitkitchen
With this comment i understand the loading parameter is available in the moment of execute the subscription, not when the call is allready doneKitkitchen
@MartijnvandenBergh : why did you mark this as the correct answer? It doesn't answer your question - the correct answer is provided by nanitohb below.Carchemish
Can you please update the reference link in apollo angular websiteIrregular
M
6

It is posible, you need to set the option notifyOnNetworkStatusChange: true, it is explained in this documentation and then use the loading prop:

this.querySubscription = this.apollo.watchQuery<any>({
  query: CurrentUserForProfile
  ,notifyOnNetworkStatusChange: true <-- This will make the trick
})
  .valueChanges
  .subscribe(({ data, loading }) => {
    this.loading = loading; <-- now this will change to false at the start of the request
    this.currentUser = data.currentUser;
  });
Macassar answered 27/8, 2020 at 17:4 Comment(0)
W
4

Your subscription has the loading parameter:

import { Component, OnInit } from '@angular/core';
import { Apollo } from 'apollo-angular';
import gql from 'graphql-tag';

// We use the gql tag to parse our query string into a query document
const CurrentUserForProfile = gql`
  query CurrentUserForProfile {
    currentUser {
  login
  avatar_url
}
  }
`;

@Component({ ... })
class ProfileComponent implements OnInit, OnDestroy {
  loading: boolean;
  currentUser: any;

  private querySubscription: Subscription;

  constructor(private apollo: Apollo) {}

  ngOnInit() {
    this.querySubscription = this.apollo.watchQuery<any>({
      query: CurrentUserForProfile
    })
      .valueChanges
      .subscribe(({ data, loading }) => {
        this.loading = loading;
        this.currentUser = data.currentUser;
      });
  }

  ngOnDestroy() {
    this.querySubscription.unsubscribe();
  }
}

https://www.apollographql.com/docs/angular/basics/queries.html

Wordless answered 24/5, 2018 at 14:5 Comment(5)
I understand that, but what use does it have and more importantly how can i use it? I cant see the importance of it because i can do it myself much easier: When making a call i set a boolean 'loading' to true, when i receive the call i set it back to false. The boolean parameter provided bu GraphQL is only available to me when the call is already done, right?Saturniid
The watchQuery method returns a QueryRef object which has the valueChanges property that is an Observable. We can see that the result object contains loading, a Boolean indicating if the query is "in-flight.": github.com/apollographql/apollo-angular/blob/master/docs/source/…Kitkitchen
With this comment i understand the loading parameter is available in the moment of execute the subscription, not when the call is allready doneKitkitchen
@MartijnvandenBergh : why did you mark this as the correct answer? It doesn't answer your question - the correct answer is provided by nanitohb below.Carchemish
Can you please update the reference link in apollo angular websiteIrregular
F
2

Here is the WatchQueryOptions in ApolloClient 3

export interface WatchQueryOptions<TVariables> extends CoreWatchQueryOptions<TVariables> {
    /**
     * Observable starts with `{ loading: true }`.
     * There's a big chance the next major version will enable that by default.
     *
     * Disabled by default
     */
    useInitialLoading?: boolean;
}

meaning you still need to explicitly tell you want to be notified of the "loading" statuschange flagging (useInitialLoading: true), otherwise you will only get false.

const variables = {};
return apollo
   .watch(variables, { useInitialLoading: true })
   .valueChanges
   .subscribe(({data, loading})=> console.log(loading)));

Note: If you still experience problems, use a version greater than the 2.4

Faber answered 12/4, 2021 at 9:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.