i Have a json file that is fetched from my server, i'd like to save the data into a map using a model, what's the proper way to do it?
I've created a model to decode the json data. My json file has some "[ ]" if i use another json file (single item) without "[ ]" it works but not with the bracket.
Here is my model
class RestoModel {
// int id;
String name;
RestoModel(this.name);
RestoModel.fromJson(Map<String, dynamic> data) {
name = data['name'];
}
}
My fetch function
List<RestoModel> restaurantList = [];
void fetchRestaurants() async {
var response = await get('https://link/get_list.php');
var data = RestoModel.fromJson(json.decode(response.body));
setState(() {
restaurantList.add(data);
print(response.body);
});
}
i get this error
Unhandled Exception: type 'List<dynamic>' is not a subtype of type 'Map<String, dynamic>'
Here is my json data
[{"id":"1","name":"Resto 1"},{"id":"3","name":"Resto 2\r\n"}]
but my code works with this json data
{
"name": "beatae et provident et ut vel",
}
I want the json file to be saved in the List but i get this error
Unhandled Exception: type 'List<dynamic>' is not a subtype of type 'Map<String, dynamic>'
{"id":"1","name":"Resto 1"} is a map, [{"id":"1","name":"Resto 1"},{"id":"3","name":"Resto 2\r\n"}] is a List of Map. So basically when you're decoding your json, you've ended up with list of model, id:1 and id:2. You're trying to give List of dynamics to your named constructor which takes a single Map as a parameter, not list of them.
Try this:
Iterable i = json.decode(response.body);
List<RestoModel> restaurantList = i.map((model) => RestoModel.fromJson(model)).toList();
In this code, I have an iterable, and for each restaurant data in that iterable I'm creating restomodel from json.
Related
How do I read a value from below response payload. From the second property in this JSON object, how do I fetch the value for the 'status' i.e "Active" or any other value for response key.
{
"signature": "1hdj12493039282849922",
"response": "{'UsersList':[{'userName':'Madan Jones','mobileNumber':'767780987','status':'Active','statusCode':null}],'status':0,'messageCode':null,'message':null,'errorMap':null}"
}
Any help is greatly appreciated!! Thanks in advance!!
Your response contains just a text that only looks like another json. So in order to do a check you have to fetch that value, parse it and hope that it would be a valid json too.
public static void main(String[] args) throws JsonProcessingException {
String str = RestAssured
.get("http://demo1954881.mockable.io/textjson")
.jsonPath().get("response");
JsonPath jsonPath = new JsonPath(str.replace("'", "\""));
String status = jsonPath.get("UsersList.find{u -> u.userName = 'Madan Jones'}.status");
MatcherAssert.assertThat(status, Matchers.equalTo("Active2"));
}
In your particular example JsonPath does not like that your field names are wrapped with ' so I change them to be proper double-quotes.
I'm trying to construct a https Uri that looks like this:
static Uri accountGetFavoriteMovies(int accountId, LoginInformation loginInfo,
{int page = 1}) {
final url = '/account/$accountId/favorite/movies';
final uri = _resolveUri(
url,
query: {
'api_key': _apiKey,
'session_id': loginInfo.sessionId,
'page': page,
},
);
return uri;
}
And what _resolveUri does simply a wrapper to Uri.https constructor:
Uri _resolveUri(String path, {Map<String, dynamic>? query}) {
return Uri.https(
_authority,
_basePath + path,
query,
);
}
Theoretically this should be working fine, but when I tested it, and I got this message:
type 'int' is not a subtype of type Iterable<dynamic>
Where's the problem?
I am convinced the problem is in the query parameter because of this stack:
_resolveUri
_AccountUrls.accountGetFavoriteMovies
_AccountRequest.favoriteMoviesRequest
Although the type for queryParameters is Map<String, dynamic>, the value expected by Uri.https is actually String or Iterable<String>.
I found this comment in the source code of the Uri library on github while trying to debug your question.
A value in the map must be either a String, or an Iterable of strings,
where the latter corresponds to multiple values for the same key.
Source of the Quote
Other Comment of Importance
I am trying to parse data from a json. I think this image will help you to understand the problem.
I am getting
Exception has occurred.
_TypeError (type '(dynamic) => MainRank' is not a subtype of type '(String, dynamic) => MapEntry<dynamic, dynamic>' of 'transform')
If you hover over the body, you will see the black pop up with the data. ranks is a list and there are two extra properties there as well.
My MainRank class is like this
class MainRank{
String divisionName;
String tournamentName;
final List<Ranks> ranks;
MainRank(this.divisionName, this.tournamentName, this.ranks);
factory MainRank.fromJson(Map<String, dynamic> json) =>
_$MainRankFromJson(json);
Map<String, dynamic> toJson() => _$MainRankToJson(this);
}
Please help me with a little bit explanation how it works in dart. I am from php/js background so data types seems giving me hard time :) Thank you,
EDIT
Response from my api is
{
ranks: [....],
divisionName: "Division 2",
tournamentName: "Season 4"
}
And code I am using to parse the json is
Future _getData() async{
var res = await CallApi().getData('standings/${widget.id}');
final body = json.decode(res.body);
// final matches = body['matches'];
var data;
if(body!=null){
data = body.map((el) => MainRank.fromJson(el));
}
print(data);
return null;
}
You want to get the MainRank from your json data, so :
Change this :
var data;
if(body!=null){
data = body.map((el) => MainRank.fromJson(el));
}
To this:
MainRank data;
if(body!=null){
data = MainRank.fromJson(body);
}
I am trying to map one field value to other if that is null or zero. I am using Gson library to parse Json. Is there any way to map values on condition base. I tried using JsonAdapter where I can put condition for that field but unable to find out solution how to get other field value there to put in that.
Write your own deserializer implementing JsonDeserializer<Element> something like below according json response-
class CustomDeserializer implements JsonDeserializer<Element> {
#Override
public Element deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context) throws JsonParseException {
JsonObject jobject = json.getAsJsonObject();
JsonObject object = jobject.get("key").getAsJsonObject();
if(object == null){
}
return null;
}
}
Usage -
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Element.class, new CustomDeserializer());
Gson gson = gsonBuilder.create();
I'm writing a Flutter Plugin that sends a List of Maps (List<Map<String, double>>) from the Platform specific side. On the Platform specific side, I'm sending these Objects using the Default Message Codec.
// (example: Android side)
List<Map<String, Double>> out = new ArrayList<>();
... fill the map ...
result.success(out);
I'm receiving these values as follows on the Dart side:
static Future<List<Map<String, double>>> getListOfMaps() async {
var traces = await _channel.invokeMethod('getListOfMaps');
print(traces); // works
return traces;
}
Printing the values gives the correct values. However, on the Function Return, I'm getting the following Error type 'List<dynamic>' is not a subtype of type 'FutureOr<List<Map<String, double>>>' on run-time, indicating that the cast from the dynamic value to the specific Map<String, double> didn't work.
How do I cast nested values coming from MethodChannels correctly in Dart?
As pointed out in the comments, I have to cast every value with unknown runtime type individually to the expected type.
static Future<List<Map<String, double>>> getListOfMaps() async {
List<dynamic> traces = await _channel.invokeMethod(...);
return traces
.cast<Map<dynamic, dynamic>>()
.map((trace) => trace.cast<String, double>())
.toList();
}
You can now use invokeListMethod:
Since invokeMethod can only return dynamic maps, we instead create a new typed list using List.cast.
var channel = MethodChannel('foo_channel');
var list = await channel.invokeListMethod<Map<String, double>>('methodInJava');