简体   繁体   中英

Flutter GraphQl query does not return current data

I am a little bit confused on why a GraphQL query returning a list of items does not get updated. Say I have a list of three items, then I add another item and rebuild the widget. The widget still only shows the first three items, even though I can see that new item has been created in the database. I am unsure if this is a cache problem. I have tried to fetch data from the.network only, but that does not work either.

The client used in the GraphQLProvider is instantiated like this:

Future<ValueNotifier<GraphQLClient>> _getClient() async {
    final HttpLink httpLink = HttpLink(
      Constants.apiURL,
      defaultHeaders: {
        'X-Parse-Application-Id': Constants.kParseApplicationId,
        'X-Parse-Client-Key': Constants.kParseClientKey,
      },
    );

    // initialize Hive and wrap the default box in a HiveStore
    Directory directory = await pathProvider.getApplicationDocumentsDirectory();
    final store = await HiveStore.open(path: directory.path);
    return ValueNotifier(
      GraphQLClient(
        cache: GraphQLCache(store: store),
        link: httpLink,
      ),
    );
  }

And the page looks like this. When a new forum post is created, setstate() is called and the widget rebuilds. However, the line List<dynamic> forumEntries = result.data?["getForumEntries"]; still returns the old list of data without the new entry. I have the same problem in a few other places as well.

class FeedWidget extends StatefulWidget {
  const FeedWidget({Key? key}) : super(key: key);

  @override
  State<FeedWidget> createState() => _FeedWidgetState();
}

class _FeedWidgetState extends State<FeedWidget> {
  final TextEditingController controller = TextEditingController();

  void _createForumPost() async {
    Map<String, dynamic> inputVariables = {
      "questionText": controller.text,
    };

    GraphQLClient client = GraphQLProvider.of(context).value;
    await client.query(
      QueryOptions(
        document: gql(GraphQLQueries.createForumPost),
        variables: inputVariables,
      ),
    );

    setState(() {
      controller.text = "";
    });
  }

  @override
  Widget build(BuildContext context) {
    return Query(
      options: QueryOptions(
          fetchPolicy: FetchPolicy.networkOnly,
          document: gql(GraphQLQueries.getForumEntries),
      ),
      builder: (QueryResult result,
          {VoidCallback? refetch, FetchMore? fetchMore}) {
        if (result.hasException) {
          return Text(result.exception.toString());
        }
        if (result.isLoading) {
          return const Center(child: CircularProgressIndicator());
        }

        List<dynamic> forumEntries = result.data?["getForumEntries"];

        return Column(
          crossAxisAlignment: CrossAxisAlignment.end,
          children: [
            Row(
              children: [
                Expanded(
                  child: TextField(
                    controller: controller,
                    keyboardType: TextInputType.multiline,
                    maxLines: null,
                    autocorrect: false,
                    decoration: InputDecoration(
                      fillColor: Theme.of(context).colorScheme.surface,
                      labelText: "Content",
                      filled: true,
                      border: InputBorder.none,
                    ),
                  ),
                ),
                const Padding(padding: EdgeInsets.symmetric(horizontal: 3)),
                CustomIconButton(
                  padding: EdgeInsets.zero,
                  icon: const Icon(Icons.send),
                  onPressed: () => _createForumPost(),
                ),
              ],
            ),
            const Padding(padding: EdgeInsets.only(bottom: 10)),
            Expanded(
              child: ListView.builder(
                shrinkWrap: true,
                itemCount: forumEntries.length,
                itemBuilder: (BuildContext context, int index) {
                  Map<String, dynamic> entry = forumEntries[index];
                  return ForumEntryWidget(entry);
                },
              ),
            ),
          ],
        );
      },
    );
  }
}

Hellow there, i was stucked with this and solved easily using refetch functions returned by Query, as your CustomIconButton are inside the Query you can replace _createForumPost() by refetch(), in my case i use on the RefreshIncator creating a function Future who calls the refetch method.

 @override Widget build(BuildContext context) { // resp = ListView(); return Scaffold( body: Query( options: QueryOptions( document: gql(documentQ), fetchPolicy: FetchPolicy.noCache, cacheRereadPolicy: CacheRereadPolicy.ignoreAll, optimisticResult: true), builder: (QueryResult result, {Refetch? refetch, FetchMore? fetchMore}) { if (result.isLoading) { return const Center(child: CircularProgressIndicator()); } if (result.data == null) { return const Center(child: Text('Nenhum tour por perto')); } return _toursView(result, refetch); }, ), ); } RefreshIndicator _toursView(QueryResult result, refetch) { // print(result.data?['tourAll']); Future<void> refresh(refetch) { return refetch(); } final toursList = result.data?['tourAll']; return RefreshIndicator( onRefresh: () => refresh(refetch), child: ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM