0
votes

I'm using HydratedBloc in Flutter. In order to work with HydratedBloc, I need to convert my custom List(parsed from JSON string) List<List<Category>> to Map<String, dynamic>. Here is the model that I'm using to parse my json string

import 'dart:convert';

List<List<Category>> rpTrendingCategoriesFromJson(String str) => List<List<Category>>.from(json.decode(str).map((x) => List<Category>.from(x.map((x) => Category.fromJson(x)))));

String rpTrendingCategoriesToJson(List<List<Category>> data) => json.encode(List<dynamic>.from(data.map((x) => List<dynamic>.from(x.map((x) => x.toJson())))));

class Category {
  Category({
    this.title,
    this.imageLink,
  });

  String title;
  String imageLink;

  factory Category.fromJson(Map<String, dynamic> json) => Category(
    title: json["title"] == null ? null : json["title"],
    imageLink: json["imageLink"] == null ? null : json["imageLink"],
  );

  Map<String, dynamic> toJson() => {
    "title": title == null ? null : title,
    "imageLink": imageLink == null ? null : imageLink,
  };
}

And here I need to convert that List<List<Category>> to Map<String, dynamic>

class TrendingCategoriesCubit extends Cubit<TrendingCategoriesState>
    with HydratedMixin {
  Repository repository;

  TrendingCategoriesCubit({@required this.repository})
      : super(TrendingCategoriesLoading());

  Future<void> fetchTrendingCategories() async {
    emit(TrendingCategoriesLoading());
    List<List<Category>> categories =
        await repository.fetchTrendingCategories();
    if (categories.isEmpty) {
      emit(TrendingCategoriesFetchedEmpty());
    } else if (categories.isNotEmpty) {
      emit(TrendingCategoriesFetched(categories: categories));
    }
  }

  @override
  TrendingCategoriesState fromJson(Map<String, dynamic> json) {
    try {
      final categories = rpTrendingCategoriesFromJson(json.toString());
      return TrendingCategoriesFetched(categories: categories);
    } catch (_) {
      return null;
    }
  }

  @override
  Map<String, dynamic> toJson(TrendingCategoriesState state) {
    if (state is TrendingCategoriesFetched) {
      return state.categories.toJson(); //coudn't do it
    } else {
      return null;
    }
  }
}

If you look at the toJson() method above, I need to return List<List<Categor>> to Map<String,dynamic. How can I do it?

1

1 Answers

0
votes

A simple workaround to achieve the desired result would be to just create a Map for the toJson/fromJson part of the Hydrated BLoC:

@override
TrendingCategoriesState fromJson(Map<String, dynamic> json) {
  try {
    final categoriesJson = json['categories'];
    final categories = rpTrendingCategoriesFromJson(json.toString());
    return TrendingCategoriesFetched(categories: categories);
  } catch (_) {
    return null;
  }
}

@override
Map<String, dynamic> toJson(TrendingCategoriesState state) {
  if (state is TrendingCategoriesFetched) {
    return <String, dynamic>{
      'categories': state.categories.toJson(),
    };
  } else {
    return null;
  }
}

Just adjust the code a little bit for it to compile, but the general idea is to create a "temporary" Map object only to persist and restore the hydrated state.