Mickro2010
Mickro2010

Reputation: 11

How to pick and show particular values from json with dart (flutter)?

I am an absolute beginner and would appreciate your help very much. My json is as follows:

[
  {
    "id": "hmip.0.homes.18c6789e-30e6-46c3-ba4b-1f94d284c178.weather.humidity",
    "val": 73,
    "ts": 1661671736783,
    "ack": true
  },
  {
    "id": "hmip.0.homes.18c6789e-30e6-46c3-ba4b-1f94d284c178.weather.temperature",
    "val": 16.8,
    "ts": 1661671736782,
    "ack": true
  },
  {
    "id": "hmip.0.homes.18c6789e-30e6-46c3-ba4b-1f94d284c178.weather.weatherCondition",
    "val": "CLEAR",
    "ts": 1661671736783,
    "ack": true
  },
  {
    "id": "hmip.0.homes.18c6789e-30e6-46c3-ba4b-1f94d284c178.weather.weatherDayTime",
    "val": "DAY",
    "ts": 1661671736783,
    "ack": true
  },
  {
    "id": "hmip.0.homes.18c6789e-30e6-46c3-ba4b-1f94d284c178.weather.windDirection",
    "val": 10,
    "ts": 1661671736784,
    "ack": true
  },
  {
    "id": "hmip.0.homes.18c6789e-30e6-46c3-ba4b-1f94d284c178.weather.windSpeed",
    "val": 18.503999999999998,
    "ts": 1661671736784,
    "ack": true
  }
]

When I want to pick and show a particular value, e.g. for humidity, I get the following error:

type 'String' is not a subtype of 'int' of 'index'

My dart-code is as follows:

class EinzelwerteList {
  final List<Wetter> einzelwerte;

  EinzelwerteList({
    required this.einzelwerte,
  });

  factory EinzelwerteList.fromJson(List<dynamic> parsedJson) {
    List<Wetter> einzelwerte = <Wetter>[];
    einzelwerte = parsedJson.map((i) => Wetter.fromJson(i)).toList();

    return new EinzelwerteList(einzelwerte: einzelwerte);
  }
}

class Wetter {
  final String id;
  final Int val;
  final Int ts;
  final Bool ack;

  Wetter({
    required this.id,
    required this.val,
    required this.ts,
    required this.ack,
  });

  factory Wetter.fromJson(Map<String, dynamic> json) {
    return Wetter(
        id: json['id'].toString(),
        val: json['val'],
        ts: json['ts'],
        ack: json['ack']);
  }
}

Future<Wetter> fetchWetter() async {
  final response = await http.get(Uri.parse(
      'http://192.168.178.37:8087/getBulk/hmip.0.homes.18c6789e-30e6-46c3-ba4b-1f94d284c178.weather.humidity,hmip.0.homes.18c6789e-30e6-46c3-ba4b-1f94d284c178.weather.temperature,hmip.0.homes.18c6789e-30e6-46c3-ba4b-1f94d284c178.weather.weatherCondition,hmip.0.homes.18c6789e-30e6-46c3-ba4b-1f94d284c178.weather.weatherDayTime,hmip.0.homes.18c6789e-30e6-46c3-ba4b-1f94d284c178.weather.windDirection,hmip.0.homes.18c6789e-30e6-46c3-ba4b-1f94d284c178.weather.windSpeed'));

  if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
    var dataDecoded = jsonDecode(response.body);
    var humidity = dataDecoded['einzelwerte'][0]['val'].toString();
    debugPrint(humidity);

    return Wetter.fromJson(jsonDecode(response.body));
  } else {
// If the server did not return a 200 OK response,
// then throw an exception.
    throw Exception('Failed to load Wetter');
  }
}

void main() => runApp(const MyApp());

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  late Future<Wetter> futureWetter;

  @override
  void initState() {
    super.initState();
    futureWetter = fetchWetter();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Fetch Data Example',
      theme: ThemeData(
        primarySwatch: Colors.green,
        //scaffoldBackgroundColor:
      ),
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Micha lernt Flutter & Dart'),
        ),
        body: Center(
          child: FutureBuilder<Wetter>(
            future: futureWetter,
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                return Text(snapshot.data!.val.toString());
              } else if (snapshot.hasError) {
                return Text('${snapshot.error}');
              }
              return Container();
            },
          ),
        ),
      ),
    );
  }
}

What do I do wrong?

As I said I am a total newbie and try to learn. So please be patient even if I ask dumb question.

Best regards.

Upvotes: 1

Views: 32

Answers (1)

julemand101
julemand101

Reputation: 31259

There are multiple problems but the specific problem you are getting right now is the following piece of code:

    var dataDecoded = jsonDecode(response.body);
    var humidity = dataDecoded['einzelwerte'][0]['val'].toString();

The JSON does not contain a Map as the first level but instead a List. So you are getting an error since a List expects an int inside the [] while you are providing a String.

Another problem, you are going to have later, is that you are using the wrong types in your Wetter class. The types Int and Bool comes from dart:ffi and is meant to be used if you are integrating with native C code.

You should instead use int and bool.

A third problem is that val in your JSON contains a mix of types. So in your example you can see it is sometimes double and other times int and sometime String... the mix of int and double can be solved by use the num type but you need to add some custom handling for the String.

Upvotes: 1

Related Questions