Reputation: 1566
I have json where each value is encoded as base64. I want to go trough the whole tree and decode every value. This needs to be automatic. No json key can be specified in the code. It needs to go down itself. How would i go about that?
This is what I have so far
Map<String, dynamic> parseJson(String response) {
var data = json.decode(response);
// Here I need to decode from base64
return data;
}
This is what the json looks like
{
"app_title":"RnJpU8Okaw==",
"app_color":"I0ZGRUUzMw==",
"app_tabs":[
{
"title":"RW4gdGl0ZWwgw6XDpMO2w4XDhMOW",
"content":"CkxpdGUgaW5uZWjDpWxsLiA8YnIgLz4gCjxiPmhlajwvYj4gCjxoMT50ZXN0PC9oMT4KPGEgaHJlZj0iaHR0cDovL2ZyaXNrb2xhLm51Ij5FbiBsw6RuazwvYT4KPGRpdiBzdHlsZT0iY29sb3I6IGdyZWVuIj5MaXRlIGdyw7ZuIHRleHQga2Fuc2tlPzwvZGl2Pgo8aW1nIHNyYz0iaHR0cDovL2ZyaXNrb2xhLm51L2ltYWdlcy9zb2ZyaV9sb2dvdHlwLnBuZyIgLz4K"
},
{
"title":"RW4gdGl0ZWwgw6XDpMO2w4XDhMOW",
"content":"CkxpdGUgaW5uZWjDpWxsLiA8YnIgLz4gCjxiPmhlajwvYj4gCjxoMT50ZXN0PC9oMT4KPGEgaHJlZj0iaHR0cDovL2ZyaXNrb2xhLm51Ij5FbiBsw6RuazwvYT4KPGRpdiBzdHlsZT0iY29sb3I6IGdyZWVuIj5MaXRlIGdyw7ZuIHRleHQga2Fuc2tlPzwvZGl2Pgo8aW1nIHNyYz0iaHR0cDovL2ZyaXNrb2xhLm51L2ltYWdlcy9zb2ZyaV9sb2dvdHlwLnBuZyIgLz4K"
},
{
"title":"RW4gdGl0ZWwgw6XDpMO2w4XDhMOW",
"content":"CkxpdGUgaW5uZWjDpWxsLiA8YnIgLz4gCjxiPmhlajwvYj4gCjxoMT50ZXN0PC9oMT4KPGEgaHJlZj0iaHR0cDovL2ZyaXNrb2xhLm51Ij5FbiBsw6RuazwvYT4KPGRpdiBzdHlsZT0iY29sb3I6IGdyZWVuIj5MaXRlIGdyw7ZuIHRleHQga2Fuc2tlPzwvZGl2Pgo8aW1nIHNyYz0iaHR0cDovL2ZyaXNrb2xhLm51L2ltYWdlcy9zb2ZyaV9sb2dvdHlwLnBuZyIgLz4K"
}
]
}
Thanks!
Upvotes: 4
Views: 4338
Reputation: 1566
I ended up solving it myself! This is the final code:
import 'dart:async';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
Future<Map<String, dynamic>> fetchJson() async {
final res = await http.get('http://app.roboro.se/json/001');
if (res.statusCode == 200) {
return compute(parseJson, res.body);
} else {
throw Exception('Failed to load json');
}
}
Map<String, dynamic> parseJson(String response) {
return walkJson(json.decode(response));
}
Map<String, dynamic> walkJson(data) {
data.forEach((key, value) {
if (value is List == false) {
data[key] = base64Decode(value);
} else {
value.forEach((item) => item = walkJson(item));
}
});
return data;
}
String base64Decode(String encoded) {
return utf8.decode(base64.decode(encoded));
}
Upvotes: 2
Reputation: 103421
This is how you can do it, using Base64Codec
, if you use utf8.decode
you won't lose the encoding.
import 'dart:convert';
Base64Codec base64 = const Base64Codec();
Map<String, dynamic> parseJson(String response) {
final data = json.decode(response);
// Here I need to decode from base64
final dataTitle = data["app_title"];
final dataColor = data["app_color"];
//decode base64
final dataTitle64 = base64.decode(dataTitle);
final dataColor64 = base64.decode(dataColor);
//Strings
String stringTitle = utf8.decode(dataTitle64);
String stringColor = utf8.decode(dataColor64);
//content array
List<Item> list = List();
for (Map<String, dynamic> value in data["app_tabs"]){
final mapTitle = base64.decode(value["title"]);
final mapContent = base64.decode(value["content"]);
String stringTitle = utf8.decode(mapTitle);
String stringContent = utf8.decode(mapContent);
list.add(Item(stringTitle, stringContent));
}
//now you have your list of items
for(Item item in list){
print("ITEM: ${item.title} .. ${item.content}");
}
//return that list if you want
return data;
}
Upvotes: 3