I saw exmaple code something like:
class ModelBinding extends StatefulWidget {
ModelBinding({
Key key,
this.initialModel = const GalleryOptions(),
this.child,
}) : assert(initialModel != null),
super(key: key);
...
so I wrote something:
class Person {
String firstName;
Person({name}){
print(name);
}
}
class Employee extends Person {
Employee(String name) : assert(false), super(name: name);
}
main() {
var emp = new Employee('Jason');
}
No matter if it is assert(false) or assert(true), the result is same.
So what is the meaning of assert?
assert is used for debugging and it simply means the condition should be true to proceed. Let me explain:
class MyClass {
final int age;
MyClass({this.age});
void someMethod() {
// using `age` here
}
}
You might face issues in someMethod if age passed is null, so to make sure it isn't null, you use assert like:
class MyClass {
final int age;
MyClass({this.age}) : assert(age != null, "Make sure age isn't null");
void someMethod() {
// using `age` here
}
}
Related
class Foo {
final int? i;
Foo({this.i});
Foo copyWith({int? x}) {
return Foo(i: x ?? i);
}
}
void main() {
final foo = Foo(i: 0);
foo.copyWith(x: null);
print(foo.i); // prints `0` but should print `null`.
}
How can I actually pass null value to the method? In earlier Dart version copyWith() and copyWith(x: null) were two different things.
Note: I'm not looking for workarounds like making a new variable, like isNull and then deciding whether to pass null or not based on its value.
With simple copyWithwhit Dart null-safety you can't override value by null because if id is null return this.id. You need to override the value by null but not return with another value. It can solve in a few ways but I will give you the best example.
void main() {
final user = User(name: 'Dave', id: 110);
User copy = user.copyWith(id: null);
print(copy.toString()); // prints User(name: Dave, id: null).
}
class User {
User({required this.name, this.id});
final String name;
final int? id;
UserCopyWith get copyWith => _UserCopyWith(this);
#override
String toString() => 'User(name: $name, id: $id)';
}
abstract class UserCopyWith {
User call({
String name,
int? id,
});
}
class _UserCopyWith implements UserCopyWith {
_UserCopyWith(this.value);
final User value;
static const _undefined = Object();
#override
User call({
Object name = _undefined,
Object? id = _undefined,
}) {
return User(
name: name == _undefined ? value.name : name as String,
id: id == _undefined ? value.id : id as int?,
);
}
}
class Persons {
final String name;
final String age;
Persons(
this.name,
this.age,
);
void printName() {
print(name);
}
}
class Players extends Persons {}
enter image description here
Edit the class Players
class Players extends Persons {
Players(name, age): super(name, age);
}
I am trying to double-check if the User object is successfully created, but Null saftey says
the operand cannot be null, so the condition is always true
What if in a scenario where the json data contains invalid type, in this case there might be some errors when creating the user object
class User {
String? name;
String? age;
User({name, age}) {
this.name = name;
this.age = age;
}
factory User.fromJson(dynamic json) {
return User(name: json['name'], age: json['age']);
}
}
void main() {
String data = '{name: "mike",age: "2"}';
User user = User.fromJson(data);
if (user != null) { // Warning: "The operand can't be null, so the condition is always true. Remove the condition."
}
}
Please advise, Thank you! :)
If something wrong is going on creating your User object from a JSON input, it will, in your case, throw an Exception which will crash the program if not catch.
So the variable user cannot be null in your case which is what the warning is telling you.
If you want to have some kind of User.tryFromJson which returns null in case of any problems, you could add something like this to you User class:
static User? tryFromJson(dynamic json) {
try {
return User.fromJson(json);
} catch (_) {
return null;
}
}
Also, some minor comments. Your User constructor does not make much sense since you could have written the following instead:
User({this.name, this.age});
Also, I would make both arguments required and prevent the nullable types. So something like this (also changed age to int):
class User {
String name;
int age;
User({
required this.name,
required this.age,
});
factory User.fromJson(dynamic json) => User(
name: json['name'] as String,
age: json['age'] as int,
);
static User? tryFromJson(dynamic json) {
try {
return User.fromJson(json);
} catch (_) {
return null;
}
}
}
void main() {
final data = '{name: "mike",age: 2}';
final user = User.fromJson(data);
}
How do I create a null safe constructor with Syntactic sugar that would set a default value if the provided value is null?
class Person {
Person({
required this.name, //Idealy, adding (?? "friend") instead of "required" should've worked but doesn't.
required this.age,
});
String name;
int age;
greet() {
print("Hello $name");
}
}
So, I actually want something like this,
class Person {
Person({
this.name ?? "friend",
this.age ?? 0,
});
String name;
int age;
greet() {
print("Hello $name");
}
}
But, as you know this is not valid in dart. So, how actually, should I achieve this?
class Person {
Person({
String? name,
int? age,
}) : this.name = name ?? "friend",
this.age = age ?? 0;
String name;
int age;
void greet() {
print("Hello $name");
}
}
Constructor Optional Params
for selecting my proposal
select this as an answer (converted from comment with permission)
You can also use default values for your optional parameters:
class Person {
Person({
this.name = "friend",
this.age = 0,
});
String name;
int age;
greet() {
print("Hello $name");
}
}
The parameter is not required, and if you don't pass it, it gets the default value. If you do pass an argument, it must be non-null.
I'm using grails 2.3.4 and I have a domain class that embeds an object. The embedded object has a property called 'version' and it seems that this is conflicting with the 'version'-field automatically added to the database-table by GORM. The result is that the 'version'-field belonging to my embedded object isn't created in the database and as a consequence my application doesn't work properly.
My code looks like this:
class Thing {
String someText
EmbeddedThing embeddedThing
Date someDate
static embedded = ['embeddedThing']
static constraints = {
embeddedThing(unique: true)
}
}
class EmbeddedThing {
String textOfSomeSort
String version
String textOfSomeOtherSort
}
You might think that a quick fix is to rename the 'version'-property of the embedded object but the class belongs to an included sub-project (i.e. a JAR-file) that I'm not allowed to touch since other projects use it. So the solution needs to be done completely within my domain class, or at least in a manner that doesn't change the class of the embedded object.
version is a special column name, you should rename your version field within your EmbeddedThin class
I actually found a solution to this problem by using a Hibernate UserType to represent the EmbeddedThing-class.
My code now looks like this and works perfectly:
Thing.groovy:
import EmbeddedThingUserType
class Thing {
String someText
EmbeddedThing embeddedThing
Date someDate
static embedded = ['embeddedThing']
static mapping = {
version false
embeddedThing type: EmbeddedThingUserType, {
column name: "embedded_thing_text"
column name: "embedded_thing_version"
column name: "embedded_thing_other_text"
}
}
static constraints = {
embeddedThing(unique: true)
}
}
EmbeddedThing.groovy:
class EmbeddedThing {
String textOfSomeSort
String version
String textOfSomeOtherSort
}
EmbeddedThingUserType.groovy:
class EmbeddedThingUserType implements UserType {
int[] sqlTypes() {
return [StringType.INSTANCE.sqlType(),
StringType.INSTANCE.sqlType(),
StringType.INSTANCE.sqlType()]
}
Class returnedClass() {
return EmbeddedThing
}
public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner)
throws HibernateException, SQLException {
if (resultSet && names) {
return new EmbeddedThing(
textOfSomeSort: resultSet?.getString(names[0] ?: '_missing_textOfSomeSort_'),
version: resultSet?.getString(names[1] ?: '_missing_version_'),
textOfSomeOtherSort: resultSet?.getString(names[2] ?: '_missing_textOfSomeOtherSort_'))
} else {
return null
}
}
public void nullSafeSet(PreparedStatement preparedStatement, Object value, int index)
throws HibernateException, SQLException {
if (value != null) {
preparedStatement.setString(index, value?.textOfSomeSort)
preparedStatement.setString(index + 1, value?.version)
preparedStatement.setString(index + 2, value?.textOfSomeOtherSort)
} else {
preparedStatement.setString(index, '_missing_textOfSomeSort_')
preparedStatement.setString(index + 1, '_missing_version_')
preparedStatement.setString(index + 2, '_missing_textOfSomeOtherSort_')
}
}
#Override
public boolean isMutable() {
return false
}
#Override
public boolean equals(Object x, Object y) throws HibernateException {
return x.equals(y)
}
#Override
public int hashCode(Object x) throws HibernateException {
assert (x != null)
return x.hashCode()
}
#Override
public Object deepCopy(Object value) throws HibernateException {
return value
}
#Override
public Object replace(Object original, Object target, Object owner)
throws HibernateException {
return original
}
#Override
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) value
}
#Override
public Object assemble(Serializable cached, Object owner)
throws HibernateException {
return cached
}
}
Config.groovy:
grails.gorm.default.mapping = {
'user-type'( type: EmbeddedThingUserType, class: EmbeddedThing)
}
Please try version false in your 'static mapping', for the 'EmbeddedThing' class.