1

I've tried Retrofit in Flutter with given tutorial by retrofit.

My Code working when i try to implement the JsonHelper data to retrieve the post. But it does not work with my server data.

This is my Data retrieved from Server

{
    "data": [
        {
            "id": 2,
            "title": "Officiis explicabo et sed modi minus.",
            "body": "Et nihil error est tenetur optio eum. Magni molestias esse corrupti cumque excepturi aut autem.\n\nQuas pariatur aut assumenda. Optio est ullam nihil. Deleniti culpa qui fugit aspernatur qui non dolor. Deleniti et vel quasi maiores libero aut.\n\nAut repellendus occaecati sit et quasi. Aut qui quia cupiditate et totam modi nam officia. Nulla molestiae iste error et sapiente est amet sequi.\n\nVelit non voluptatem voluptas quod dolorem. Eos nesciunt perferendis quo ut dignissimos aliquid ex. Maiores sed tempore et. Molestiae dolores sed rerum.",
            "created_at": 1576508819,
            "featured_image": null,
            "user": {
                "username": "mikayla22",
                "user_since": "2019-12-16"
            },
            "categories": [
                "General",
                "Technology"
            ],
            "language": "English",
            "votes": 0
        },
    ]
}

I created podo according to the retrofit and implmented Class in Flutter

Podo :

part 'post_api_service.g.dart';

@RestApi(baseUrl: "http://142")
abstract class RestClient {
  factory RestClient(Dio dio) = _RestClient;
  @GET("/posts")
  Future<Task<List<Post>>> getPosts();

}
@JsonSerializable()
class Post{
  int id;
  String title;
  String body;
  int created_at;
  String featured_image;
  User user;
  Categories categories;
  String language;
  int votes;
  Post({this.id, this.title, this.body, this.featured_image, this.categories, this.created_at, this.language, this.user, this.votes});

  factory Post.fromJson(Map<String, dynamic> json) => _$PostFromJson(json);
  Map<String, dynamic> toJson() => _$PostToJson(this);
}

class User{
  String username;
  String user_since;

  User({this.username, this.user_since});
  factory User.from(Map<String, dynamic> json) => _$UserFromJson(json);
  Map<String, dynamic> toJson() => _$UserToJson(this);
}

class Categories{
  List<String> categories;

  Categories({this.categories});

  factory Categories.from(Map<String, dynamic> json) => _$CategoriesFromJson(json);
  Map<String, dynamic> toJson() => _$CategoriesToJson(this);
}

class Task<T>{
  T data;

  Task({this.data});

  factory Task.fromJson(Map<String, dynamic> json) => _$TaskFromJson(json);
  Map<String, dynamic> toJson() => _$TaskToJson(this);
}

and this is my

Service.g.dart:

User _$UserFromJson(Map<String, dynamic> json){
  return User(
      username: json['username'] as String,
      user_since: json['user_since'] as String
  );
}

Map<String, dynamic> _$UserToJson(User instance) => <String, dynamic>{
  'username' : instance.username,
  'user_since' : instance.user_since
};

Categories _$CategoriesFromJson(Map<String, dynamic> json){
  return Categories(
      categories: json['categories'] as List<String>
  );
}

Map<String, dynamic> _$CategoriesToJson(Categories instance) => <String, dynamic>{
  'categories' : instance.categories
};

Task _$TaskFromJson(Map<String, dynamic> json){
  return Task(
      data: json['data']
  );
}

Map<String, dynamic> _$TaskToJson(Task instance) => <String, dynamic>{
  'data' : instance.data
};


Post _$PostFromJson(Map<String, dynamic> json){
  return Post(
      id: json['id'] as int,
      user: json['user'] as User,
      categories: json['categories'] as Categories,
      body: json['body'] as String,
      created_at: json['created_at'] as int,
      featured_image: json['featured_image'] as String,
      language: json['language'] as String,
      votes: json['votes'] as int,
      title: json['title'] as String
  );
}

Map<String, dynamic> _$PostToJson(Post instance) => <String, dynamic>{
  'id' : instance.id,
  'user' : instance.user,
  'categories' : instance.categories,
  'body' : instance.body,
  'created_at' : instance.created_at,
  'featured_image' : instance.featured_image,
  'language' : instance.language,
  'votes': instance.votes,
  'title': instance.title
};

class _RestClient implements RestClient {
  _RestClient(this._dio, {this.baseUrl}) {
    ArgumentError.checkNotNull(_dio, '_dio');
    this.baseUrl ??= 'http://142';
  }

  final Dio _dio;

  String baseUrl;

  @override
  getPosts() async {
    const _extra = <String, dynamic>{};
    final queryParameters = <String, dynamic>{};
    final _data = <String, dynamic>{};
    final Response<Map<String, dynamic>> _result = await _dio.request('/posts',
        queryParameters: queryParameters,
        options: RequestOptions(
            method: 'GET',
            headers: <String, dynamic>{},
            extra: _extra,
            baseUrl: baseUrl),
        data: _data);
    final value = Task<List<Post>>.fromJson(_result.data);
    return Future.value(value);
  }
}

But when i try to get the data

builder: (context, snapshot) {
    if (snapshot.connectionState == ConnectionState.done) {
        print(snapshot.data);
        List<Post> posts = snapshot.data.data;
        return _buildPosts(context, posts);
    } else {
        return Center(
            child: CircularProgressIndicator(),
        );
    }
},

If you have any issue just ask me i'll explain from code. But confuse with output.

  • Welcome to SO! Could you post your response code as a text not an image? – Sergey Shubin Dec 18 '19 at 10:13
  • @SergeyShubin as you asked i provided the response in Text but i provided for single Post response. in `data` i am retrieve list of Posts. –  Dec 18 '19 at 10:19

1 Answers1

0

The problem i think is in this line

    final value = Task<List<Post>>.fromJson(_result.data);

you need to parse element by element from JSON to post. This could be done using a map as follows:

    final value = List<Post>.from(_result.data.map((i) => Post.fromJson(i)));
Karim
  • 962
  • 7
  • 10