Invalid Date Format - Flutter/Dart - flutter

It might be a simple solution but I have some problems with it. I have JSON response with user data like name, address, and birthday. However, birthDay is empty and I cannot parse it.
Error (only those lines occure):
Exception has occurred.
FormatException (FormatException: Invalid date format
)
I'm using tryParse and DateFormatter with null check but it seems to not work as I expect. Below you'll find part of code and JSON response:
Part of response:
birthDay: "" // as you see it's empty
bioInfo: ""
badges: List(6 items)
agreement5: false
Part of Profile Entity:
class ProfileEntity {
final String birthDay;
ProfileEntity.fromJson(Map<String, dynamic> json)
: birthDay = json['birthDay'],
}
Part of Profile Model:
class ProfileModel {
final DateTime birthDate;
ProfileModel({#required this.birthDate});
ProfileModel.fromEntities(
ProfileEntity profileEntity,
) : birthDate = DateTime.tryParse(profileEntity.birthDay), //place where I'm getting an error - value is null in this case.
//here I'm sending it to form field
Map<String, String> toFormFields() {
return {
'jform[birthDay]':
birthDate != null ? DateFormat("yyyy-MM-dd").format(birthDate) : "", //null check
}
}
}
Do you have any idea how to get rid of this? (Error message do not provide any info despite what I paste above in error part)

DateTime.tryParse does not expect null value.
You can replace this with DateTime.tryParse(profileEntity.birthDay ?? '') which will return null instead of throwing exception.
For ref: tryParse method

DateFormat('dd-MM-yyyy').parse(widget.initialDate);
remember you can change date format according to which you api sends date in my case 'dd-MM-yyy' in your case may be different format.

Related

Flutter firebase: Bad state: field does not exist within the DocumentSnapshotPlatform

I'm getting this error:
Bad state: field does not exist within the DocumentSnapshotPlatform
with the following code:
static List<Report?> reportListFromSnapshot(QuerySnapshot snapshot) {
return snapshot.docs.map<Report?>((report) {
return Report(
type: report['type'],
reason: report['reason'],
reportId: report['id'],
chat:
(report['chat'] == null) ? null : Chat.chatFromMap(report['chat']),
stingray: Stingray.stingrayFromDynamic(report['stingray']),
reporterUser: User.fromDynamic(report['reporterUser']),
reportTime: report['reportTime'].toDate(),
);
}).toList();
}
Its failing on the first map,
type: report['type'],
and when i look at it in debug mode, it shows the data i am looking for:
As you can see from the screenshot, 'type' exists with a value of 'chat report'. Any idea why this is breaking?
Thanks!
You are supposed to call .data() on report
static List<Report> reportListFromSnapshot(QuerySnapshot snapshot) {
final List<Report> reports = [];
for (final doc in snapshot.docs) {
final report = doc.data() as Map<String, dynamic>?; // you missed this line.
if (report == null) continue;
reports.push(
Report(
type: report['type'] as String,
reason: report['reason'] as String,
reportId: report['id'] as String,
chat: (report['chat'] == null)
? null
: Chat.chatFromMap(report['chat']),
stingray: Stingray.stingrayFromDynamic(report['stingray']),
reporterUser: User.fromDynamic(report['reporterUser']),
reportTime: (report['reportTime'] as Timestamp).toDate(),
),
);
}
return reports;
}
// I returned List<Report> not List<Report?>
Check out this link on how to use withConverter so you do not have to manually convert models.
The problem turned out to be larger in scope than i thought. I was uploading a map object to firebase rather than just a document, and that map was attempting to be read, which is where the error occurred due to it only having one value in the document snapshot.
Maybe you have typo in your field which does not match with your model fields. So the idea is that, your fields in your model has to match with the fields in your firebase snapshot fields.
enter link description here

MongoDB query for equal search with $regex

I have an entity
class Data {
string name;
string city;
string street;
string phone;
string email;
}
An api has been written to find Data by each param. This is search api so if a param is provided, it will be used if not then everything has to be queried for that param.
#Query("{'name': ?0,'city': ?1,'street': ?2, 'phone': ?3,'email': ?4}")
Page<IcePack> findDataSearchParams(String name,
String city,
String street,
String phone,
String email);
This only works when all the params are sent in the request. It wont work if any of the params are not sent because it will look for null value in the DB for that param.
I want to query everything for that param if it is not requested like the way it is done in SQL. I tired to use $regex with empty string when something is not sent but regex works like a like search but I want to do equal search
anyway to do this
Filtering out parts of the query depending on the input value is not directly supported. Nevertheless it can be done using #Query the $and and operator and a bit of SpEL.
interface Repo extends CrudRepository<IcePack,...> {
#Query("""
{ $and : [
?#{T(com.example.Repo.QueryUtil).ifPresent([0], 'name')},
?#{T(com.example.Repo.QueryUtil).ifPresent([1], 'city')},
...
]}
""")
Page<IcePack> findDataSearchParams(String name, String city, ...)
class QueryUtil {
public static Document ifPresent(Object value, String property) {
if(value == null) {
return new Document("$expr", true); // always true
}
return new Document(property, value); // eq match
}
}
// ...
}
Instead of addressing the target function via the T(...) Type expression writing an EvaluationContextExtension (see: json spel for details) allows to get rid of repeating the type name over and over again.

Flutter: Issue while converting json to model using json_serializable

Suppose there are two models User and City
#JsonSerializable()
class User {
int id;
String name;
City? city;
}
#JsonSerializable()
class City {
int id;
String name;
}
Now suppose during API call, we've got a user model but in the city object model, we only get id not name. Something like this
{
"id": 5,
"name": "Matthew",
"city": {
"id": 12
}
}
But due to the default nature of json_serializable and json_annotation.
This JSON is not mapped to the User model, during mapping, it throws the exception.
type Null is not a subtype of type String. (because here name key is missing in city object)
But as we already declared in the User object that City is optional, I wanted that it should parse the User JSON with city as null.
Any help or solution would be really appreciated, Thank you
There is currently no support for ignoring a certain field only while serializing or only while deserializing. You can either ignore both or none. However, there is a workaround that I use.
Make a global method in your model file that just returns null like this:
T? toNull<T>(_) => null;
Inside your User model add a custom JsonKey for City:
#JsonKey(fromJson: toNull, includeIfNull: false)
City? City;
What this does is when converting from Json it uses your specificed function for converting city and replaces your value with null. Then due to includeIfNull property it just skips parsing.

Using the Dart/Flutter Postgres Package to store dates and null dates needs two separate commands

I am using the Postgres Package (On the pub.dev site) to UPDATE records in a very simple database. It has two fields: a Text field prime key named number, and a Date field named date_of_birth.
If the date_of_birth is a valid DateTime string then all is well (as can be seen from the code below). But if date_of_birth is unknown (so I set to null) the UPDATE fails:
import 'package:postgres/postgres.dart';
void main() async {
final conn = PostgreSQLConnection(
'localhost',
XXXXX,
'XXXXX',
username: 'XXXXX',
password: 'XXXXX',
);
await conn.open();
DateTime dob = DateTime.now();
var results;
results = await conn.query('''
UPDATE account_details
SET date_of_birth = '$dob'
WHERE number = '123123'
''');
await conn.close();
}
If I set:
dob = null;
The program fails with the error:
Unhandled exception:
PostgreSQLSeverity.error 22007: invalid input syntax for type date: "null"
So I need to include a check on the dob field and the program now looks like this:
DateTime dob = DateTime.now();
dob = null;
var results;
if (dob == null) {
results = await conn.query('''
UPDATE account_details
SET date_of_birth = null
WHERE number = '123123'
''');
} else {
results = await conn.query('''
UPDATE account_details
SET date_of_birth = '$dob'
WHERE number = '123123'
''');
}
That works fine for my simple database, but in my real App. I have a number of date fields in one table. So I have to do a check for each possible combination of those date values - writing a code block for each!
Can anyone tell me how I can UPDATE both null and a valid date using a single statement please?
You are quoting the query parameters yourself. NEVER do this. In addition to the sort of problem you have just seen it also leaves you open to a trivial SQL injection attack.
The library you are using will have some way of putting placeholders into the query text and passing variables when executing the query. Use that.

Handle null value in Dart / Flutter

I have this User class and then a Firestore Document, that may or may not contain a photoURL or some other values. The problem is, that when I try to create an user I get this exception because some of the values are Null.
I've tried to handle it like this:
var photoURL = snapshot.data['photoURL'] ??= '';
but it seems it doesn't work.
Can anyone explain best practices handling Null values in Dart/Flutter respectively?
EDIT: I'm checking if snapshot.exists before and if I create the user omitting the values I know are Null, it creates it properly.
EDIT 2: I've found the problem appears when I try to handle empty List like this:
var favorites = snapshot.data['favorites'] ?? [''];
It seems I was initialized the value the wrong way when I converted it to Json.
I handle the empty Array like this
Map<String, dynamic> toJson() => {
'favorites' : favorites ?? '',
}
when it should be:
Map<String, dynamic> toJson() => {
'favorites' : favorites ?? [''],
}
So it was throwing when I tried to assign an empty Array to String.