title: Unhandled Exception: NoSuchMethodError: Class 'String' has no instance method 'forEach'
body: <p>I have an article search feature on my application by implementing BLOC and RX Dart. I have succeeded in searching the article based on the "title" that became the key in the search, but when I filled in the "title" incorrectly, the results did not issue an error such as "Article does not exist / anything else" and the results were not real-time according to the key " title "is meant and instead gets an error in LogCat as below:</p>
  
  <pre><code>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) =&gt; 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): &lt;asynchronous suspension&gt;
  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): &lt;asynchronous suspension&gt;
  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): &lt;asynchronous suspension&gt;
  E/flutter (25135): #8      MethodChannel._handleAsMethodCall (package:flutter/src/services/platform_channel.dart:397:55)
  E/flutter (25135): &lt;asynchronous suspension&gt;
  E/flutter (25135): #9      MethodChannel.setMethodCallHandler.&lt;anonymous closure&gt; (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): &lt;asynchronous suspension&gt;
  E/flutter (25135): #11     _invoke3.&lt;anonymous closure&gt; (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)
  </code></pre>
  
  <p>This is the model:</p>
  
  <pre><code>class Articles {
    int status;
    List&lt;Result&gt; result;
  
    Articles({this.status, this.result});
  
    Articles.fromJson(Map&lt;String, dynamic&gt; json) {
      status = json['status'];
      if (json['result'] != null) {
        result = new List&lt;Result&gt;();
        json['result'].forEach((v) {
          result.add(new Result.fromJson(v));
        });
      }
    }
  
    Map&lt;String, dynamic&gt; toJson() {
      final Map&lt;String, dynamic&gt; data = new Map&lt;String, dynamic&gt;();
      data['status'] = this.status;
      if (this.result != null) {
        data['result'] = this.result.map((v) =&gt; 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&lt;String, dynamic&gt; json) {
      idArtikel = json['id_artikel'];
      title = json['title'];
      sinopsis = json['sinopsis'];
      content = json['content'];
      createdDate = json['created_date'];
      thumbnail = json['thumbnail'];
    }
  
    Map&lt;String, dynamic&gt; toJson() {
      final Map&lt;String, dynamic&gt; data = new Map&lt;String, dynamic&gt;();
      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;
    }
  }
  </code></pre>
  
  <p>This is the API:</p>
  
  <pre><code>class ApiProvider {
  
    Client client = Client();
    static final String baseUrl = 'link_api';
  
    Future&lt;Articles&gt; 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');
      }
    }
  
  }
  </code></pre>
  
  <p>This is the repository:</p>
  
  <pre><code>class Repository {
  
    final apiProvider = ApiProvider();
    Future&lt;Articles&gt; searchArticlesRepository(String title) =&gt; apiProvider.searchArticle(title);
  
  }
  </code></pre>
  
  <p>This is the BLoC:</p>
  
  <pre><code>class SearchArticleBloc {
  
    final repository = Repository();
    final articleSearchFetcher = PublishSubject&lt;Articles&gt;();
    Observable&lt;Articles&gt; get allSearchArticle =&gt; articleSearchFetcher.stream;
  
    searchArticleBloc(String title) async {
      Articles articles = await repository.searchArticlesRepository(title);
      articleSearchFetcher.sink.add(articles);
    }
  
    dispose() {
      articleSearchFetcher.close();
    }
  
  }
  </code></pre>
  
  <p>And this is the UI:</p>
  
  <pre><code>class SearchArticlePage extends StatefulWidget {
    @override
    _SearchArticlePageState createState() =&gt; _SearchArticlePageState();
  }
  
  class _SearchArticlePageState extends State&lt;SearchArticlePage&gt; {
  
    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 &lt;Widget&gt;[
              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&lt;Articles&gt; 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&lt;Articles&gt; 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: &lt;Widget&gt;[
                      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: &lt;Widget&gt;[
                              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}',
                    );
                  }),
                );
              },
            );
          },
        ),
      );
    }
  
  }
  </code></pre>
  
  <p>Can someone help me? Because I was dizzy to find a solution to this error :)</p>