Flutter 未处理的异常:NoSuchMethodError:Class';字符串';没有实例方法';forEach&x27;
通过实现BLOC和RX Dart,我的应用程序上有一个文章搜索功能。我已经成功地根据成为搜索关键字的“标题”搜索了文章,但是当我错误地填写“标题”时,结果没有出现错误,例如“文章不存在/其他任何内容”,并且根据关键字“标题”搜索结果不是实时的意味着,而是在LogCat中获取一个错误,如下所示:Flutter 未处理的异常:NoSuchMethodError:Class';字符串';没有实例方法';forEach&x27;,flutter,bloc,Flutter,Bloc,通过实现BLOC和RX Dart,我的应用程序上有一个文章搜索功能。我已经成功地根据成为搜索关键字的“标题”搜索了文章,但是当我错误地填写“标题”时,结果没有出现错误,例如“文章不存在/其他任何内容”,并且根据关键字“标题”搜索结果不是实时的意味着,而是在LogCat中获取一个错误,如下所示: E/flutter (25135): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: NoSuchMethodError
E/flutter (25135): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: NoSuchMethodError: Class 'String' has no instance method 'forEach'.
E/flutter (25135): Receiver: "Data not found"
E/flutter (25135): Tried calling: forEach(Closure: (dynamic) => Null)
E/flutter (25135): #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:50:5)
E/flutter (25135): #1 new Articles.fromJson (package:vallery/src/models/articles/articles.dart:11:22)
E/flutter (25135): #2 ApiProvider.searchArticle (package:vallery/src/resources/api/api_provider.dart:65:23)
E/flutter (25135): <asynchronous suspension>
E/flutter (25135): #3 Repository.searchArticlesRepository (package:vallery/src/resources/repository/repository.dart:19:74)
E/flutter (25135): #4 SearchArticleBloc.searchArticleBloc (package:vallery/src/blocs/article/articles_search_bloc.dart:12:42)
E/flutter (25135): <asynchronous suspension>
E/flutter (25135): #5 EditableTextState._formatAndSetValue (package:flutter/src/widgets/editable_text.dart:1335:14)
E/flutter (25135): #6 EditableTextState.updateEditingValue (package:flutter/src/widgets/editable_text.dart:971:5)
E/flutter (25135): #7 _TextInputClientHandler._handleTextInputInvocation (package:flutter/src/services/text_input.dart:743:36)
E/flutter (25135): <asynchronous suspension>
E/flutter (25135): #8 MethodChannel._handleAsMethodCall (package:flutter/src/services/platform_channel.dart:397:55)
E/flutter (25135): <asynchronous suspension>
E/flutter (25135): #9 MethodChannel.setMethodCallHandler.<anonymous closure> (package:flutter/src/services/platform_channel.dart:365:54)
E/flutter (25135): #10 _DefaultBinaryMessenger.handlePlatformMessage (package:flutter/src/services/binary_messenger.dart:110:33)
E/flutter (25135): <asynchronous suspension>
E/flutter (25135): #11 _invoke3.<anonymous closure> (dart:ui/hooks.dart:280:15)
E/flutter (25135): #12 _rootRun (dart:async/zone.dart:1124:13)
E/flutter (25135): #13 _CustomZone.run (dart:async/zone.dart:1021:19)
E/flutter (25135): #14 _CustomZone.runGuarded (dart:async/zone.dart:923:7)
E/flutter (25135): #15 _invoke3 (dart:ui/hooks.dart:279:10)
E/flutter (25135): #16 _dispatchPlatformMessage (dart:ui/hooks.dart:141:5)
E/flatter(25135):[错误:flatter/lib/ui/ui\u dart\u state.cc(148)]未处理的异常:NoSuchMethodError:类“String”没有实例方法“forEach”。
E/颤振(25135):接收器:“未找到数据”
E/flatter(25135):尝试调用:forEach(闭包:(动态)=>Null)
E/颤振(25135):#0 Object.noSuchMethod(省道:核心补片/Object_补片。省道:50:5)
E/flatter(25135):#1 new Articles.fromJson(包:vallery/src/models/Articles/Articles.dart:11:22)
E/flatter(25135):#2 ApiProvider.searchArticle(包:vallery/src/resources/api/api_provider.dart:65:23)
E/颤振(25135):
E/flatter(25135):#3 Repository.searchArticlesRepository(包:vallery/src/resources/Repository/Repository.dart:19:74)
E/flatter(25135):#4 SearchArticleBloc.SearchArticleBloc(包:vallery/src/blocs/article/articles_search_bloc.dart:12:42)
E/颤振(25135):
E/flatter(25135):#5 EditableTextState.(格式和设置值(包:flatter/src/widgets/EditableText.dart:1335:14)
E/flatter(25135):#6 EditableTextState.updateEditingValue(包:flatter/src/widgets/EditableText.dart:971:5)
电子/颤振(25135):#7文本输入clienthandler.#手工输入职业(软件包:颤振/src/services/text输入。dart:743:36)
E/颤振(25135):
E/颤振(25135):#8方法频道。"HandlesMethodCall(套餐:颤振/src/服务/平台"频道。dart:397:55)
E/颤振(25135):
E/颤振(25135):#9 MethodChannel.setMethodCallHandler。(包装:颤振/src/services/platform_通道。dart:365:54)
E/flatter(25135):#10#DefaultBinaryMessenger.handlePlatformMessage(包:flatter/src/services/binarymessenger.dart:110:33)
E/颤振(25135):
E/颤振(25135):#11#。(省道:ui/挂钩。省道:280:15)
E/flatter(25135):#12 rootRun(dart:async/zone.dart:1124:13)
E/flatter(25135):#13 _CustomZone.run(dart:async/zone.dart:1021:19)
E/颤振(25135):#14#CustomZone.runguard(dart:async/zone.dart:923:7)
E/颤振(25135):#15#调用3(省道:ui/挂钩。省道:279:10)
E/flatter(25135):#16"调度平台消息(dart:ui/hooks.dart:141:5)
这就是模型:
class Articles {
int status;
List<Result> result;
Articles({this.status, this.result});
Articles.fromJson(Map<String, dynamic> json) {
status = json['status'];
if (json['result'] != null) {
result = new List<Result>();
json['result'].forEach((v) {
result.add(new Result.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['status'] = this.status;
if (this.result != null) {
data['result'] = this.result.map((v) => v.toJson()).toList();
}
return data;
}
}
class Result {
String idArtikel;
String title;
String sinopsis;
String content;
String createdDate;
String thumbnail;
Result(
{this.idArtikel,
this.title,
this.sinopsis,
this.content,
this.createdDate,
this.thumbnail});
Result.fromJson(Map<String, dynamic> json) {
idArtikel = json['id_artikel'];
title = json['title'];
sinopsis = json['sinopsis'];
content = json['content'];
createdDate = json['created_date'];
thumbnail = json['thumbnail'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id_artikel'] = this.idArtikel;
data['title'] = this.title;
data['sinopsis'] = this.sinopsis;
data['content'] = this.content;
data['created_date'] = this.createdDate;
data['thumbnail'] = this.thumbnail;
return data;
}
}
类文章{
智力状态;
列出结果;
项目({this.status,this.result});
fromJson(映射json){
status=json['status'];
if(json['result']!=null){
结果=新列表();
json['result'].forEach((v){
add(newresult.fromJson(v));
});
}
}
映射到JSON(){
最终地图数据=新地图();
数据['status']=this.status;
如果(this.result!=null){
data['result']=this.result.map((v)=>v.toJson()).toList();
}
返回数据;
}
}
班级成绩{
线状伊达蒂克尔;
字符串标题;
线蕨;
字符串内容;
字符串创建数据;
字符串缩略图;
结果(
{this.idArtikel,
这个名字,
这是中国的,
这个.内容,,
这个.createdDate,
这个});
fromJson(映射json){
idArtikel=json['id_artikel'];
title=json['title'];
sinopsis=json['sinopsis'];
content=json['content'];
createdDate=json['created_date'];
缩略图=json['thumbnail'];
}
映射到JSON(){
最终地图数据=新地图();
数据['id_artikel']=this.idArtikel;
数据['title']=this.title;
数据['sinopsis']=此为sinopsis;
数据['content']=this.content;
数据['created_date']=this.createdDate;
数据['thumbnail']=this.thumbnail;
返回数据;
}
}
这是API:
class ApiProvider {
Client client = Client();
static final String baseUrl = 'link_api';
Future<Articles> searchArticle(String title) async {
final response = await client.post(baseUrl + 'search-artikel', body: {
"title" : title
});
if (response.statusCode == 200) {
return Articles.fromJson(json.decode(response.body));
} else {
throw Exception('Gagal ambil data article');
}
}
}
类API提供程序{
Client=Client();
静态最终字符串baseUrl='link_api';
Future searchArticle(字符串标题)异步{
最终响应=wait client.post(baseUrl+搜索artikel),正文:{
“头衔”:头衔
});
如果(response.statusCode==200){
return Articles.fromJson(json.decode(response.body));
}否则{
抛出异常(“Gagal ambil数据项目”);
}
}
}
这是存储库:
class Repository {
final apiProvider = ApiProvider();
Future<Articles> searchArticlesRepository(String title) => apiProvider.searchArticle(title);
}
类存储库{
最终apiProvider=apiProvider();
Future searchArticlesRepository(字符串标题)=>apiProvider.searchArticle(标题);
}
这是一个集团:
class SearchArticleBloc {
final repository = Repository();
final articleSearchFetcher = PublishSubject<Articles>();
Observable<Articles> get allSearchArticle => articleSearchFetcher.stream;
searchArticleBloc(String title) async {
Articles articles = await repository.searchArticlesRepository(title);
articleSearchFetcher.sink.add(articles);
}
dispose() {
articleSearchFetcher.close();
}
}
class SearchArticleBloc{
最终存储库=存储库();
final articleSearchFetcher=PublishSubject();
Observable get allSearchArticle=>articleSearchFetcher.stream;
searchArticleBloc(字符串标题)异步{
Articles=等待存储库。SearchArticles存储库(标题);
articleSearchFetcher.sink.add(文章);
}
处置{
articleSearchFetcher.close();
}
}
这是用户界面:
class SearchArticlePage extends StatefulWidget {
@override
_SearchArticlePageState createState() => _SearchArticlePageState();
}
class _SearchArticlePageState extends State<SearchArticlePage> {
final blocSearchArticle = SearchArticleBloc();
@override
void dispose() {
blocSearchArticle.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: color_white,
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
backgroundColor: color_white,
iconTheme: IconThemeData(
color: color_blue_bg, //change your color here
),
centerTitle: true,
floating: true,
pinned: true,
title: TextField(
autofocus: true,
style: TextStyle(fontSize: 17, color: color_blue_bg),
decoration: InputDecoration.collapsed(
hintText: "Article Name...",
hintStyle: TextStyle(fontSize: 17, color: color_blue_bg),
),
onChanged: blocSearchArticle.searchArticleBloc,
),
)
];
},
body: getListResult(),
),
);
}
Widget getListResult() {
return StreamBuilder(
stream: blocSearchArticle.allSearchArticle,
builder: (BuildContext context, AsyncSnapshot<Articles> snapshot) {
if(snapshot.hasData) {
return showListResult(snapshot);
} else if (!snapshot.hasData) {
return Center(
child: Text('Data not found'),
);
} else if(snapshot.hasError) {
return Text(snapshot.error.toString());
}
return Center(
child: CircularProgressIndicator(),
);
},
);
}
Widget showListResult(AsyncSnapshot<Articles> snapshot) {
return Container(
margin: EdgeInsets.only(top: 10.0),
child: ListView.builder(
shrinkWrap: true,
physics: ClampingScrollPhysics(),
scrollDirection: Axis.vertical,
itemCount: snapshot.data.result == null ? Center(child: Text('Data not found')) : snapshot?.data?.result?.length ?? 0,
itemBuilder: (BuildContext context, int index) {
return GestureDetector(
child: Container(
height: MediaQuery.of(context).size.height / 7.0,
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: Row(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Container(
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
child: FadeInImage.assetNetwork(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width / 3,
placeholder: 'assets/images/img_default_bg.png',
image: '${snapshot.data.result[0].thumbnail}',
fit: BoxFit.cover,
),
),
),
Expanded(
child: Container(
margin: EdgeInsets.only(
left: MediaQuery.of(context).size.width / 41,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: EdgeInsets.only(
right: MediaQuery.of(context).size.width/41,
bottom: MediaQuery.of(context).size.width/ 80,
),
child: Text(
snapshot.data.result[index].title,
overflow: TextOverflow.ellipsis,
maxLines: 1,
style: TextStyle(
color: Colors.black,
fontSize: MediaQuery.of(context).size.width / 25,
fontWeight: FontWeight.bold,
),
),
),
Padding(
padding: EdgeInsets.only(
right: MediaQuery.of(context).size.width/41,
bottom: MediaQuery.of(context).size.width/ 80,
),
child: Text(
snapshot.data.result[index].sinopsis,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Colors.black,
fontSize: MediaQuery.of(context).size.width / 35,
fontWeight: FontWeight.normal,
),
),
),
SizedBox(height: MediaQuery.of(context).size.height / 50,
),
Padding(
padding: EdgeInsets.only(
right: MediaQuery.of(context).size.width/41,
bottom: MediaQuery.of(context).size.width/ 80,
),
child: Text(
snapshot.data.result[index].createdDate,
style: TextStyle(
color: Colors.black,
fontSize: MediaQuery.of(context).size.width / 35,
fontWeight: FontWeight.normal,
),
),
),
],
),
),
),
],
),
),
),
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (context){
return ArticleDetailPage(
id: snapshot.data.result[index].idArtikel,
title: snapshot.data.result[index].title,
thumbnail: '${snapshot.data.result[index].thumbnail}',
);
}),
);
},
);
},
),
);
}
}
class SearchArticlePage扩展StatefulWidget{
@凌驾
_SearchArticlePageState createState()=>\u SearchArticlePageState();
}
类_SearchArticlePageState扩展状态{
final blocSearchArticle=SearchArticleBloc();
@凌驾
无效处置(){
blocSearchArticle.dispose();
super.dispose();
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
背景颜色:白色,
正文:嵌套滚动视图(
headerSliverBuilder:(BuildContext上下文,boolInnerBoxIsCrolled){
返回[
滑杆(
背景颜色:白色,
iconTheme:IconThemeData(
颜色:颜色\蓝色\背景,//在此处更改颜色
),
标题:对,
浮动:是的,
对,,
if (json['result'] != null) {
result = new List<Result>();
json['result'].forEach((v) {
result.add(new Result.fromJson(v));
});
}
result = json['result'].map<Result>((j) => Result.fromJson(j).toList();