Flutter二次进入SiteMap页面无法获取GraphQL数据报错求助
Hey there! Let's break down why you're hitting this error and how to fix it quickly.
First, the core issues here are two things:
- Unchecked null values: When you navigate back to the page, your query is returning
nullforresult.data["sitemaps"]["sitemaps"], but your code tries to loop over it directly without verifying it exists. - GraphQL caching behavior: By default, the GraphQL client caches query results. When you return to the page, it might pull from an incomplete or stale cache instead of re-fetching fresh data from your backend.
Step 1: Add Null Safety Checks (Immediate Fix)
First, let's stop the error by ensuring we never try to iterate over a null list. Update your list assignment to use null-aware operators and a fallback empty list:
List _sitemaps = result.data?["sitemaps"]?["sitemaps"] ?? [];
The ? operator safely checks if each nested key exists before accessing it, and ?? [] guarantees we get an empty list instead of null if any step fails.
Step 2: Force Fresh Data on Page Navigation
If stale cache is the culprit, tell the Query to always fetch fresh data from the network instead of relying on cache. Modify your QueryOptions to include a fetchPolicy:
Query( options: QueryOptions( document: getSitemapsGSCQuery(), fetchPolicy: FetchPolicy.networkOnly, // Bypass cache, get fresh data every time ), builder: (QueryResult result,{VoidCallback refetch, FetchMore fetchMore}) { // ... your existing builder code (with the null-safe list assignment above) }, )
This ensures every time you navigate to the SiteMap page, the query hits your backend again instead of using potentially incomplete cached data.
Step 3: Add Defensive Checks for Better UX
For a more robust solution, add checks to handle missing data gracefully and give users a way to retry:
builder: (QueryResult result,{VoidCallback refetch, FetchMore fetchMore}) { if (result.errors != null) { return Text(result.errors.toString()); } if (result.loading) { return Text('Loading'); } // Check if any nested data is missing final sitemapData = result.data?["sitemaps"]?["sitemaps"]; if (sitemapData == null) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text("Couldn't load sitemap data"), SizedBox(height: 16), ElevatedButton( onPressed: refetch, child: Text('Retry'), ), ], ), ); } // Now we can safely loop over sitemapData List _sitemaps = sitemapData; for (var sitemap in _sitemaps) { // Execute your operations } // Return your main UI here },
Why This Happened
As a Flutter beginner, it's easy to overlook how GraphQL clients handle caching. When you first load the page, the query fetches fresh data and caches it. But when you navigate away and come back, the client might pull from that cache—if for some reason the cached data doesn't have the sitemaps key (maybe the cache was cleared, or the initial query had a different structure), you end up with null and the iterator error. Adding null safety and controlling the fetch policy fixes both issues.
内容的提问来源于stack exchange,提问作者songjie

