How to correctly pass a model as a string using jsonEncode / jsonDecode in dart

Viewed 57

Problem summarization

I'm using a SreamTransformer to validate a simple String value, for that I'm calling a Future<String> fetchCountry function which makes an API call and parses the response to a Country class. I'm trying to return the class as a String like so :

static Future<String> fetchCountry(country) async {
...
 print('fetch ok');// this is printed

return jsonEncode(Country(
   continent: continent,
   country: countryR,
   population: population,
   newcases: newcases,
   activecases: activecases,
   criticalcases: criticalcases,
   recoveredcases: recoveredcases,
   totalcases: totalcases,
   newdeaths: newdeaths,
   totaldeaths: totaldeaths,
   day: day));
}

The call is made and returns 200 although this function always returns null

What I've tried:

  • read flutter docs for Json Serialization
  • I was returning a Country from fetchCountry but changed it to String since the Stream can't read Country objects

The code inside the validator:

 Future<String> future = FetchCountry.fetchCountry(country);
 future.then((value) {
         print('$value'); //this is always null!!
         sink.add(value);
       }).catchError((err) {
          sink.addError("$country is not a country from future");
 // this is shown but the future doesn't return Future.error on `fetch ok` message
      });

This is my stream builder:

StreamBuilder(
          stream: bloc.getCountryStream,
          builder: (context,AsyncSnapshot<String> snapshot){
            print('snapshot: ${snapshot.data}');
            if(snapshot.hasData){

             final Map country = jsonDecode(snapshot.data);
              return Container(
                margin: EdgeInsets.all(30),
                child: Column(
                  children: [
                    Container(
                      margin: EdgeInsets.only(top: 20),
                      child: Text(' ${country['country']}is found :)'),
                    ),
                  ],
                ),
              );
            }else{
              return Text('something went wrong');
            }
          },
        )

Logs

I/flutter ( 4533): {get: statistics, parameters: {country: Greece}, errors: [], results: 1, response: [{continent: Europe, country: Greece, population: 10399817, cases: {new: +639, active: 111497, critical: 558, recovered: 9989, 1M_pop: 12036, total: 125173}, deaths: {new: +62, 1M_pop: 355, total: 3687}, tests: {1M_pop: 248989, total: 2589438}, day: 2020-12-15, time: 2020-12-15T09:15:07+00:00}]}
I/flutter ( 4533): fetch ok
I/flutter ( 4533): snapshot: null

Last but not least the Country model class:

class Country {
  String country;
  String continent;
  int population;
  String newcases;
  int activecases;
  int criticalcases;
  int recoveredcases;
  int totalcases;
  String newdeaths;
  int totaldeaths;
  String day;
  Country(
      {this.country,
      this.continent,
      this.population,
      this.newcases,
      this.activecases,
      this.criticalcases,
      this.recoveredcases,
      this.totalcases,
      this.newdeaths,
      this.totaldeaths,
      this.day});
}

What have I completely missed and I can't properly return a json string?

1 Answers

The flutter documentation you referenced has a toJson method in the plain class for User - does your country code need the same?

From the User example:

Map<String, dynamic> toJson() =>
{
  'name': name,
  'email': email,
};
Related