5

I'm having trouble converting HTTP response body to a Flutter list. In a debugger, the output of jsonDecode(response.body)['data']['logsread'] looks exactly like

[
   {
      "id": "9fd66092-1f7c-4e60-ab8f-5cf7e7a2dd3b",
      "email": "email@gmail.com"
   }
]

Yet, this returns false.

print((jsonDecode(response.body)['data']['logsread']) ==
[{
      "id": "9fd66092-1f7c-4e60-ab8f-5cf7e7a2dd3b",
      "email": "email@gmail.com"
}]);  // This returns false.

FYI. response.body =>

"{"data":{"logsread":[{"id":"9fd66092-1f7c-4e60-ab8f-5cf7e7a2dd3b","email":"email@gmail.com"}]}}"
Nirav Vasoya
  • 356
  • 3
  • 18
Jason O.
  • 3,168
  • 6
  • 33
  • 72

4 Answers4

4

JsonDecode returns List<dynamic> but your another list is of type List<Map<String,String>>. So convert it to same type of list by creating to any Model and overriding == and hashcode.

and to compare two list you need ListEquality function. example :

    Function eq = const ListEquality().equals;
    print(eq(list1,list2));

I tried your code and done my way, check if this okay.

Model class:

    class Model {
        String id;
        String email;

        Model({
          this.id,
          this.email,
        });

        factory Model.fromJson(Map<String, dynamic> json) => new Model(
              id: json["id"],
              email: json["email"],
            );

        Map<String, dynamic> toJson() => {
              "id": id,
              "email": email,
            };


        @override
        bool operator ==(Object other) =>
            identical(this, other) ||
                other is Model &&
                    runtimeType == other.runtimeType &&
                    id == other.id &&
                    email == other.email;

        @override
        int get hashCode =>
            id.hashCode ^
            email.hashCode;

      }

main.dart

    import 'package:collection/collection.dart';

    var body =
            '{"data":{"logsread":[{"id":"9fd66092-1f7c-4e60-ab8f-5cf7e7a2dd3b","email":"email@gmail.com"}]}}';
        var test1 = (jsonDecode(body)['data']['logsread'] as List)
            .map((value) => Model.fromJson(value))
            .toList();
        var test2 = ([
          {"id": "9fd66092-1f7c-4e60-ab8f-5cf7e7a2dd3b", "email": "email@gmail.com"}
        ]).map((value)=>Model.fromJson(value)).toList();

        Function eq = const ListEquality().equals;
        print(eq(test1,test2));

I hope this is what you are looking for.

Xuzan
  • 335
  • 1
  • 11
2

You should also provide position of the object you want to retrieve id from. Did you try doing this?

Example:

var id = ['data']['logsread'][0]['id'];
var email= ['data']['logsread'][0]['email'];

I mostly do this.

Amit Jangid
  • 2,741
  • 1
  • 22
  • 28
  • Thanks, but adding [0] will isolate the Map within the List. I'm trying to compare List (jsonDecode result) with List (defined using literal [ ]). – Jason O. Feb 14 '19 at 07:55
1

Your parse is correct, but I think that's not the right way to compare list of maps. I think that doing == you're simply comparing the objects and not their content.

I suggest you to check here for map compare and here for list compare.

This way you would be checking the contents, and not roughly the objects (which are two different instances, so yeah technically they're different even if they have the same contents).

magicleon94
  • 4,887
  • 2
  • 24
  • 53
0

Try to first convert into the map and then use

import 'dart:convert';

//Decode response string to map
Map<String, dynamic> map = json.decode("jsonString");

xyz = map['data']['logsread'];
kishansinh
  • 91
  • 1
  • 8
  • Thanks, but the equation still returns false after replacing `jsonDecode(..)` with `map` as you suggested. – Jason O. Feb 14 '19 at 07:57