Skip to content
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

Query refetch not working #346

Closed
Wisdom0063 opened this issue Jun 24, 2019 · 26 comments
Closed

Query refetch not working #346

Wisdom0063 opened this issue Jun 24, 2019 · 26 comments
Assignees
Labels
🐛 bug Something isn't working flutter Issue relates mainly to graphql_flutter 🐣 good first issue Good for newcomers help wanted Extra attention is needed
Projects

Comments

@Wisdom0063
Copy link

  options: QueryOptions(
    document: readRepositories, // this is the query string you just created
    variables: {
      'nRepositories': 50,
    },
    pollInterval: 10,
  ),
  // Just like in apollo refetch() could be used to manually trigger a refetch
  builder: (QueryResult result, { VoidCallback refetch }) {
    if (result.errors != null) {
      return Text(result.errors.toString());
    }

    if (result.loading) {
      return Text('Loading');
    }

    // it can be either Map or List
    List repositories = result.data['viewer']['repositories']['nodes'];

    return ListView.builder(
      itemCount: repositories.length,
      itemBuilder: (context, index) {
        final repository = repositories[index];

     return  FloatingActionButton(
        onPressed: refetch(),
        tooltip: 'Increment',
        child: Icon(Icons.add),
      )
    });
  },
);```
 I calling refetch() but I am not seeing the output
@lucasavila00
Copy link
Contributor

I haven't had this problem. It would be useful if you could provide a better reproduction. Try to base it on the example of this project and maybe one would help.

@Wisdom0063
Copy link
Author

Wisdom0063 commented Jun 26, 2019

This is sample of my code where I am using a refetch()



   return Query(
                            options: QueryOptions(
                                document: getUserprofile,
                                variables: {"user_id": userId},
                            ),
                            builder: (QueryResult nResult, {VoidCallback refetch}) {
                                if(nResult.loading == false) {
                                    if(nResult.data != null) {
                                        nData = nResult.data["getUserProfile"]["on_the_menu"];
                                        return Stack(
                                            children: <Widget>[
                                                Container(
                                                    child: CustomScrollView(
                                                        slivers: <Widget>[
                                                            SliverPersistentHeader(
                                                                pinned: true,
                                                                delegate: RecipeHeader(
                                                                    minExtent: ScreenUtil.instance.setHeight(450),
                                                                    maxExtent: ScreenUtil.instance.setHeight(450),
                                                                    recipeImage: data["pictures"][0],
                                                                    recipeName: data["name"],
                                                                    recipeTime: data["time"],
                                                                    recipeLevel: data["difficulty_level"],
                                                                    recipeServing: data["number_of_servings"],
                                                                    recipePercentage: data["ingredients_percentage"],
                                                                    isRecipeLiked: IconButton(
                                                                        icon: nData.where((value)=>value["_id"] == widget.recipeIdRP).isNotEmpty ? Image.asset(
                                                                            likeRecipe,
                                                                        ) : Image.asset(
                                                                            unlikeRecipe,
                                                                        ),
                                                                        iconSize: ScreenUtil.instance.setHeight(40),
                                                                        splashColor: Colors.transparent,
                                                                        onPressed: () {
                                                                            if(nData.where((value)=>value["_id"] == widget.recipeIdRP).isNotEmpty) {
                                                                                removeMenu();
                                                                                return refetch();
                                                                            } else {
                                                                                addMenu();
                                                                          return refetch();

                                                                            }
                                                                        },
                                                                    )
                                                                ),
                                                            ),```

@Wisdom0063
Copy link
Author

Wisdom0063 commented Jun 26, 2019

I have been following the documentation but it isnt working for me. That is a portion of my code where I used the refetch(). Everything else is working except that

@JeffersonCarvalh0
Copy link

I'm also experiencing a similar issue. I'm trying to use refetch with the RefreshIndicator widget, but new data isn't being fetched

@guilhermedecampo
Copy link

@lucasavila00 can you add here the snippet that works for you?

@micimize
Copy link
Collaborator

My best guess is that there's some issue with the observable query lifecycle updating in your specific scenario. Please provide more details, like fetchPolicy and possibly the lifecycle when you break the debugger on refetch() and descend into it's context

Also, if you're results get populated from the cache first, maybe it'll work after the first network request completes.

Also, format your code snippets. And I assume you meant this in your first example

return FloatingActionButton(
- onPressed: refetch(),
+ onPressed: refetch,
  tooltip: 'Increment',
  child: Icon(Icons.add),
)

This is the refetch code in observable_query.dart I think is suspect:

  bool get _isRefetchSafe {
    switch (lifecycle) {
      case QueryLifecycle.COMPLETED:
      case QueryLifecycle.POLLING:
      case QueryLifecycle.POLLING_STOPPED:
        return true;

      case QueryLifecycle.PENDING:
      case QueryLifecycle.CLOSED:
      case QueryLifecycle.UNEXECUTED:
      case QueryLifecycle.SIDE_EFFECTS_PENDING:
      case QueryLifecycle.SIDE_EFFECTS_BLOCKING:
        return false;
    }
    return false;
  }

  /// Attempts to refetch, returning `true` if successful
  bool refetch() {
    if (_isRefetchSafe) {
      queryManager.refetchQuery(queryId);
      return true;
    }
    return false;
  }

@Wisdom0063
Copy link
Author

I didn't provide any fetchPolicy in my code. So I guess I am using the default

@JeffersonCarvalh0
Copy link

JeffersonCarvalh0 commented Jul 4, 2019

@micimize I debugged my code here, and could state that my query lifecicle is PENDING every time I call refetch. My fetch policy is cacheAndNetwork . What can possibly the issue in this case?

@JeffersonCarvalh0
Copy link

Even when my fetchPolicy is networkOnly, the status keeps PENDING

@micimize
Copy link
Collaborator

micimize commented Jul 4, 2019

@JeffersonCarvalh0 to clarify, you:

  1. run a query with fetchPolicy=networkOnly
  2. get results from the network, no logged errors, the component renders with data
  3. attempt to refetch, but lifecycle=PENDING, so it fails?

If so, this is likely a regression

@JeffersonCarvalh0
Copy link

Exactly. The query that is performed when the widget is built works perfectly. The problem only happens when I try to refetch.

@Wisdom0063
Copy link
Author

@JeffersonCarvalh0 I needed to be able to refetch so I found a hack around pollInterval. I initially set pollInterval to null so when the person clicks on the button to refetch I call setState to change pollInterval to say 2. So after the request is successful I call setState again to change pollInterval to null . It is not the best of idea but for now don't have any option

@JeffersonCarvalh0
Copy link

Thanks, @Wisdom0063, it worked like a charm here!

@guilhermedecampo
Copy link

@mainawycliffe this is still a problem. Why did you close the issue? Do we have a PR fixing it?

What they guys did was just a workaround.

@mainawycliffe
Copy link
Collaborator

@guilhermedecampo I am sorry. Thought it was resolved, judging by the last comment. I am reopening it, will look in to it over the week. Can you reproduce the issue on a small repo, may be using the GitHub API?

@mainawycliffe mainawycliffe reopened this Jul 14, 2019
@mainawycliffe mainawycliffe self-assigned this Jul 14, 2019
@mainawycliffe mainawycliffe added 🐛 bug Something isn't working flutter Issue relates mainly to graphql_flutter labels Jul 14, 2019
@mainawycliffe mainawycliffe removed their assignment Jul 14, 2019
@mainawycliffe mainawycliffe added 🐣 good first issue Good for newcomers help wanted Extra attention is needed labels Jul 14, 2019
@mainawycliffe mainawycliffe added this to To do in Open Scrum via automation Jul 14, 2019
@mainawycliffe mainawycliffe self-assigned this Jul 14, 2019
@mainawycliffe mainawycliffe moved this from To do to Queued for Work in Open Scrum Jul 14, 2019
@serendipity1004
Copy link
Collaborator

@mainawycliffe any directions for this? like @Wisdom0063 said, lifecycle is always pending so refetch is always unsafe. If you are too busy, just point me to right direction and I'll try to find the root cause.

@mainawycliffe
Copy link
Collaborator

@serendipity1004 this completely slipped under my radar, I am sorry about that. I will look into it in the course of the week and share my thoughts on the way forward.

@guilhermedecampo
Copy link

amazing @mainawycliffe

@mainawycliffe
Copy link
Collaborator

@serendipity1004 I can't still reproduce this error with the examples we have, though I am using the latest version which is yet to release. refetch is working as expected as far as I can tell If I can't reproduce the issue I can't debug it. Maybe it was fixed inadvertently by a previous PR, can someone please confirm if they are still getting the same error using the latest beta.

@mainawycliffe
Copy link
Collaborator

A repo reproducing the issue would be very useful, this way I can jump right in to debug the issue.

@onemanstartup
Copy link

For me, it's working with the latest beta.

@micimize
Copy link
Collaborator

micimize commented Nov 7, 2019

If anyone still has this issue on beta, please comment and I'll reopen. Given not everyone had the issue, it might have just been a beta vs master release issue

@micimize micimize closed this as completed Nov 7, 2019
Open Scrum automation moved this from Queued for Work to Done Nov 7, 2019
@blaugold
Copy link
Contributor

I just ran into a related problem, I think.

I have a watch query which uses FetchPolicy.cacheFirst and I want to use refetch at some later point to refresh the query. The problem is that the ObservableQuery is getting stuck in QueryLifecycle.pending after the initial call to fetchResults and throws when calling refetch.

I suspect the root cause is in the order of the call to fetchQueryAsMultiSourceResult and setting lifecycle. If the query has eager results, fetchQueryAsMultiSourceResult will synchronously trigger a call to addResult, which is responsible for setting lifecycle to QueryLifecycle.completed. Then lifecycle is set to QueryLifecycle.pending, but without a network request
lifecycle is never updated again.

  MultiSourceResult fetchResults() {
    final MultiSourceResult allResults =
        queryManager.fetchQueryAsMultiSourceResult(queryId, options);
    latestResult ??= allResults.eagerResult;

    // if onData callbacks have been registered,
    // they are waited on by default
    lifecycle = _onDataCallbacks.isNotEmpty
        ? QueryLifecycle.sideEffectsPending
        : QueryLifecycle.pending;

    if (options.pollInterval != null && options.pollInterval > Duration.zero) {
      startPolling(options.pollInterval);
    }

    return allResults;
  }

@micimize
Copy link
Collaborator

@blaugold I'd consider this a different issue, but based on what you're saying it seems unlikely to me that you need to refetch. Any changes to the underlying data in the cache will trigger a rebroadcast on the observable query automatically,refetch only refetches from the network, overriding the fetchPolicy because there is never a reason to refetch from the cache:
https://github.com/zino-app/graphql-flutter/blob/2efce9f15e59208d86a2c4b1c9e0794cc28ea680/packages/graphql/lib/src/core/query_manager.dart#L294-L308

Might be a bit different on master – I recommend switching to beta if you aren't already on it

@blaugold
Copy link
Contributor

@micimize Thanks for all the work on this package. I would like to use only the cache if the data is available and let the user trigger a refresh from the server whenever they want to. I thought that was possible with a combination of FetchPolicy.cacheFirst and refetch. Am I missing something?

@micimize
Copy link
Collaborator

@blaugold no that's correct – I misunderstood you, now I see what you were saying. I think you're correct. Made #771 to track it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🐛 bug Something isn't working flutter Issue relates mainly to graphql_flutter 🐣 good first issue Good for newcomers help wanted Extra attention is needed
Projects
No open projects
Open Scrum
  
Done
Development

No branches or pull requests

9 participants