I'm having problem using fromJson in flutter. I'm receiving my data like this
{id: d7ba912e-69fd-11ea-9ab0-6597c4120b03, receipt_date: 2020-03-18T17:30:00.000Z, customer_id: e3fedf5e, amount: 2500, remark: Amount 2500, created_on: 2020-03-19T16:22:35.000Z, collectionSize: 3, name: Customer 1}
And I'm using this fromJson to parse:
factory CashReceipt.fromJson(Map<String, dynamic> json) {
return CashReceipt(
id: json['id'],
customerId: json['customer_id'],
date: json['date'] as DateTime,
amount: json['amount'] as double,
remark: json['remark']);
}
The "amount" property is double in my model. It is causing following error. The data coming from API is "amount:2500". It goes away if I change the "amount" to "int". But it is not right. Your help is much appreciated.
_CastError (type 'int' is not a subtype of type 'double' in type cast)
You can use
num amount
instead of
double amount
and you will not get this error. see this doc
Related
I'm trying to hook some function in an class it works fine but I want to view one argumant that is an class instance and this class has field that is String type, but when I try to get this field I get some really weird type instead of the string
Here is the code:
var someclass = Java.use('com.myapp.classes.someclass.a');
// String (Object, String, Boolean)
someclass.getData.overload('com.myapp.classes.ClassContext',
'java.lang.String', 'java.lang.Boolean').implementation = function (a, b, c) {
console.log('com.myapp.classes.ClassContext.stringify: ',
JSON.stringify(a.fieldWithStringData), '\r\n');
}
But instead of string I get some weird object when I used JSON.stringify on this object I got string like this (pretty printed for this question):
{
"_p": ["<instance: com.myapp.classes.ClassContext>", 2, {
"className": "java.lang.String",
"name": "Ljava/lang/String;",
"type": "pointer",
"size": 1,
"defaultValue": "0x0"
}, "0xa3144614", "0xc2aaa8b0", "0xc2aace70"]
}
What is this object and how to get actual string from it, can some one help?
You can use like this: a.fieldWithStringData.value
in Swift or Kotlin I can do something like this
var fullName = myMap["fullName"] as? String
then as a result that fullName data type will be optional String ( String? ).
I need to get optional type after type checking like that
I can't directly perform null coalescing operator to that map, because dart will give weird result. for example like this
// 'data' is Map<String, dynamic>
final fullName = data["fullname"] ?? "John Doe";
final double myNumber = fullName;
as you can see, the IDE will not show an error at all, I expect that fullName will be a String, so it will have an error when I assign a String to myNumber that require double.
If you know in advance that data["fullname"] is a String, then you could do:
final fullName = (data["fullname"] ?? "John Doe") as String;
If data["fullname"] turns out not to be a String at runtime, you'll get a runtime exception from the cast failure. If that's something you need to handle, then you could easily make a trivial helper function that checks if a dynamic value is the desired type first and that returns null if it isn't:
T? tryCast<T>(dynamic object) => object is T ? object : null;
final fullName = tryCast<String>(data["fullname"]) ?? "John Doe";
and now fullName is statically known to be a String, and accidentally assigning it to a double will be a compile-time error.
The safe nullable cast operator known from Kotlin currently doesn't exist in Dart but it soon might.
In your case though, why not simply write
String? fullname = myMap["fullname"];
The nullable cast operator as? in Kotlin yields null if myMap["fullname"] contains anything but a non-null String. As long as you're only dealing with Strings or null, the above works just fine. (And if there's anything but a String or null it crashes, which is probably better than just continue on with null in most situations)
Good day, I am trying to apply named parameter {num phone} to the below example:
main(){
showInfo("abc#mail.com", "Fatima");
}
String showInfo(String email, String name, {num phone}) {
print(email);
print(name);
print(phone);
return "$email : $name : $phone";
}
but I receive the error:
Error: The parameter 'phone' can't have a value of 'null' because of its type 'num', but the implicit
default value is 'null'.
Try adding either an explicit non-'null' default value or the 'required' modifier.
Future<String> showInfo(String email, String name, {num phone}) async {
^^^^^
your help is appreciated.
You marked the parameter as a num, which means it cannot be null. However, the default for named parameters that are not used is null, so you cannot have a named parameter that is optional with a default value of null with a datatype that does not accept null.
One option is to give it a default value other than null:
String showInfo(String email, String name, {num phone = 0})
Another option is to make it a named, but required parameter, so it will never get a default value:
String showInfo(String email, String name, {required num phone})
Another alternative is to actually keep the phone optional:
String showInfo(String email, String name, {num? phone})
Some additional wisdom: phone numbers can start with leading zeroes that are important and should not be deleted on saving it. You cannot use num for a phone number, you will have to use string.
The error is pretty clear, you have to pass a value to the phone parameter or add a default value. This is due to the introduction of Null Safety in Dart 2.12.
You can pass a value like this :
showInfo("abc#mail.com", "Fatima", phone: 0);
Or add a default value to the phone parameter :
String showInfo(String email, String name, {num phone = 0}) {
print(email);
print(name);
print(phone);
return "$email : $name : $phone";
}
If you want, you can use Dart <2.12 to avoid Null Safety, your code should work properly then.
I have a little problem with parse JSON data.
There have a Web APIļ¼basic response data like this:
{
topic_name: "Kevin",
topic_type: 1,
extraData: {}
}
With the different topic_type value, the extraData maybe have different data structure, e.g the extraData object has different key-values.
In this case, how to create model classes and parse the JSON string to models?
Or does this API design reasonable? Is there a better API design to solve these cases?
update 1:
With the same topic_type, the extraData's structure is always same.
I have considered use subclasses, but it need a subclass for every topic_type.
update 2:
Here is some example of JSON data, different topic_type with different extraData.
when topic_type equal to 1,
{
topic_name: "Kevin",
topic_type: 1,
extraData: {
data_type1: value,
data_type2: value2
}
}
when topic_type equal to 2,
{
topic_name: "David",
topic_type: 2,
extraData: {
data_type3: value3
}
}
it not real data, I'm not deal with a 'topic' issue, just a example, the key is the extraData object has different type keys.
JSONModel might be exactly what you're looking for. Parses json and gives you models
try to define all types in a class:
{
topic_name: "Kevin",
topic_type: 1,
extraData: {
data_type1: value,
data_type2: value2,
data_type3: value3,
}
}
after Json parsing, take the data types u need based on topic type.
Ps. All data types need to be nullable
The domain looks like
class EventDonation implements Serializable{
String title
String body
Integer customDonationMin
Integer customDonationMax
EntityStatus status
List denominations
static hasMany = [denominations: Integer]
}
Please note that the denominations is a list of Integers. Now during binding
List<String> whiteList = ['title', 'body', 'customDonationMin', 'customDonationMax', 'denominations']
bindData(don, params, ['include': whiteList])
if(params.status){
don.status = EntityStatus.ACTIVE
}
else{
don.status = EntityStatus.INACTIVE
}
don.validate()
if(don.hasErrors()){
render(view: "editdonation", model: [id:id, donation:don])
return
}
The following error is displayed
Message: java.lang.String cannot be cast to java.lang.Integer
In the view page there are 4 textboxes for entering denominations. I was thinking that the strings i.e '10', '20', '30', '40' will automatically be converted to integers during binding. I think the error is associated with binding this list. I appreciate any help. Thanks!
Interesting thing is when i change the type of the list to String as follows:
class EventDonation implements Serializable{
String title
String body
Integer customDonationMin
Integer customDonationMax
EntityStatus status
List denominations
static hasMany = [denominations: String]
}
The following binding works fine i.e no error is thrown.
List<String> whiteList = ['title', 'body', 'customDonationMin', 'customDonationMax', 'denominations']
bindData(don, params, ['include': whiteList])
if(params.status){
don.status = EntityStatus.ACTIVE
}
else{
don.status = EntityStatus.INACTIVE
}
don.validate()
if(don.hasErrors()){
render(view: "editdonation", model: [id:id, donation:don])
return
}
So, i am confident that the type Integer for the list is the source of the problem. Since denominations are integers i cannot think of any other type. I appreciate any help on this. Thank you!