gpt4 book ai didi

my Future builder is returning error i have no clue what to do(我的Future Builder返回错误,我不知道该怎么做)

转载 作者:bug小助手 更新时间:2023-10-25 20:25:00 40 4
gpt4 key购买 nike



here is my Future builder its returning an error i think its because of riverpod but i cant find a solution. the error is at the bottom
i tried changedDependencies and didnt work im receiving the list normally and its showing in the console but its not showing in initState.
my objective is to have self loading list whenever the page starts yet everything is fine concerning the data handling the list is being received and the api is connecting its just the snapshot.data is turning out null for some reason.
its my first time using this type of builder so im hoping im clear enough on the matter.

这是我的未来构建器,它返回了一个错误,我想这是因为河舱,但我找不到解决方案。错误在底部,我尝试更改依赖项,但没有工作,我正常接收列表,并在控制台中显示,但它不在initState中显示。我的目标是在页面启动时自动加载列表,但在数据处理方面一切正常,列表正在被接收,API正在连接它的快照。由于某种原因,数据变成了空。这是我第一次使用这种类型的建筑商,所以我希望我对这件事足够清楚。


import 'dart:convert';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import '../models/account.dart';
import '../provider/company_provider.dart';
import '../provider/user_provider.dart';

class AccountFinder extends ConsumerStatefulWidget {
const AccountFinder({super.key});

@override
ConsumerState<AccountFinder> createState() => _AccountFinderState();
}

class _AccountFinderState extends ConsumerState<AccountFinder> {
late Future<List<Account>> accounts;
String searchString = "";
Future<List<Account>> fetchAccounts() async {
var userID = ref.watch(userStateProvider).id;
var companyID = ref.watch(companyStateProvider).comID;
print(userID);
final url = Uri.parse(
'http://api_adress/GetAllActs?CID=$companyID',
);
final headers = {'Content-Type': 'application/json'};
final response = await http.post(
url,
headers: headers,
body: json.encode({
"id": userID,
"userName": "string",
"password": "string",
"loggedIn": true,
"userActive": true,
"userDeleteable": true
}),
);

if (response.statusCode == 200) {
List<dynamic> listAccountsJson = jsonDecode(response.body);

return listAccountsJson
.map((account) => Account.fromJson(account))
.toList();
} else {
throw Exception('Failed to load items');
}
}

@override
void initState() {
super.initState();
accounts = fetchAccounts();
}

@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SafeArea(
child: Container(
height: 40,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Theme.of(context)
.colorScheme
.onBackground
.withOpacity(0.1)),
margin: const EdgeInsets.symmetric(horizontal: 10, vertical: 20),
child: TextField(
onTapOutside: (event) =>
FocusManager.instance.primaryFocus?.unfocus(),
onChanged: (value) {
setState(() {
searchString = value.toLowerCase();
});
},
style: Theme.of(context).textTheme.bodyMedium!,
decoration: InputDecoration(
border: InputBorder.none,
hintText: AppLocalizations.of(context)!.search,
hintStyle: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 16,
fontWeight: FontWeight.w300,
color: Theme.of(context)
.colorScheme
.onBackground
.withOpacity(0.7)),
prefixIcon: const Icon(
Icons.search,
)),
),
),
),
IconButton(onPressed: fetchAccounts, icon: Icon(Icons.abc)),
const SizedBox(height: 10),
Expanded(
child: FutureBuilder(
builder: (context, AsyncSnapshot<List<Account>> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error}'));
} else if (!snapshot.hasData) {
return Center(child: Text('No data available'));
} else {
return SingleChildScrollView(
child: ListView.separated(
padding: const EdgeInsets.all(8),
itemCount: snapshot.data!.length,
itemBuilder: (BuildContext context, int index) {
return snapshot.data![index].actName!
.toLowerCase()
.contains(searchString)
? Card(
elevation: 3,
child: ListTile(
title: Text('${snapshot.data?[index].actName}'),
subtitle: Text(
' ${snapshot.data?[index].actMobileNo}\n${snapshot.data?[index].actPhoneNo}\n'),
),
)
: Container();
},
separatorBuilder: (BuildContext context, int index) {
return snapshot.data![index].actName!
.toLowerCase()
.contains(searchString)
? const Divider()
: Container();
},
),
);
}
},
future: accounts,
),
),
],
);
}
}


This the error im getting:

这就是我得到的错误:


dependOnInheritedWidgetOfExactType<UncontrolledProviderScope>() or dependOnInheritedElement() was called before _AccountFinderState.initState() completed.
I/flutter (14799): When an inherited widget changes, for example if the value of Theme.of() changes, its dependent widgets are rebuilt. If the dependent widget's reference to the inherited widget is in a constructor or an initState() method, then the rebuilt dependent widget will not reflect the changes in the inherited widget.
I/flutter (14799): Typically references to inherited widgets should occur in widget build() methods. Alternatively, initialization based on inherited widgets can be placed in the didChangeDependencies method, which is called after initState and whenever the dependencies change thereafter.```



更多回答

Once you have riverpod, you do not need FutureBuilder or StreamBuilder any more. Just ref.watch the futureprovider or the streamprovider, and use .when on the result to choose one of many branches.

一旦拥有了Riverpod,您就不再需要FutureBuilder或StreamBuilder。只需引用.查看未来提供程序或流提供程序,并在结果上使用.When从多个分支中选择一个。

try to wrap with try-catch and then log the snapshot error

尝试使用try-Catch进行包装,然后记录快照错误

优秀答案推荐

The error message you're getting provides a clear hint about the problem:

您收到的错误消息提供了有关问题的明确提示:



dependOnInheritedWidgetOfExactType<UncontrolledProviderScope>() or dependOnInheritedElement() was called before _AccountFinderState.initState() completed.



Inherited widgets, which Riverpod's providers are built upon, cannot be accessed in initState(). This is because initState() is called before the widget is fully integrated into the widget tree, which means it doesn't yet have access to the context from the widgets above it.

继承的小部件是Riverpod提供程序所基于的,不能在initState()中访问。这是因为initState()是在小部件完全集成到小部件树之前调用的,这意味着它还不能从上面的小部件访问上下文。


Here's the solution based on the error:

以下是基于该错误的解决方案:


1. Use didChangeDependencies:


Instead of fetching the data in initState(), override the didChangeDependencies() method which is called immediately after initState() and whenever the dependencies (like providers) change:

不是在initState()中获取数据,而是覆盖didChangeDependents()方法,该方法在initState()之后立即调用,并在依赖项(如提供程序)发生更改时调用:


@override
void didChangeDependencies() {
super.didChangeDependencies();

// Check if accounts is not already set or you can use another mechanism
// to ensure you don't call fetchAccounts() multiple times
if (accounts == null) {
accounts = fetchAccounts();
}
}

Note: Be cautious when using didChangeDependencies(). It can be called multiple times throughout the lifecycle of a widget, especially if the widget depends on multiple InheritedWidgets (e.g., providers, themes, etc.). Thus, you'll want to make sure you don't redundantly re-fetch data.

注意:使用didChangeDependency()时要小心。在小部件的整个生命周期中,它可以被多次调用,特别是当小部件依赖于多个InheritedWidget(例如,提供者、主题等)时。因此,您需要确保不会冗余地重新获取数据。


2. Remove the call from initState():


You can now remove the data fetching from the initState() method:

现在可以删除从initState()方法获取的数据:


@override
void initState() {
super.initState();
// Remove accounts = fetchAccounts(); from here
}

By making this adjustment, you should no longer see the error related to accessing Riverpod providers (or any InheritedWidgets) inside initState().

通过进行此调整,您应该不会再看到与访问initState()中的Riverpod提供程序(或任何InheritedWidget)相关的错误。



i gave it a Future.delayed(Duration.zero,fetchAccounts()); and its working fine now the real error turned out to be in the widget overlay the constraint werent contraining so the devider had no widtth to be based upon and removed the future builder entirely and left it with ListView.seperated

我给了它一个Future.Delayed(Duration.ero,fetchAccount());它现在工作得很好,现在真正的错误是在小部件覆盖中约束没有约束,所以分割器没有宽度可供参考,并完全删除了未来的构建器,将其留给了ListView.Seperated


更多回答

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.

正如它目前所写的,你的答案并不清楚。请编辑以添加更多详细信息,以帮助其他人了解这是如何解决提出的问题的。你可以在帮助中心找到更多关于如何写出好答案的信息。

40 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com