`toString` method adding null to object in Dart - dart

I am working on a Flutter web app, and am using a custom class to keep track of form data. I am instantiating a new instance of the following class:
class Contact {
String name;
String relationship;
String phoneNo;
#override
String toString() {
print("""{
Name: $name,
Relation: $relationship,
Phone: $phoneNo
}""");
}
}
In my controller, once I instantiate, I am printing out the value immediately:
// Method in controller, triggered by onTap
Contact contact = Contact();
print(contact);
The output is:
{
Name: null,
Relation: null,
Phone: null
}
null
Which is causing issues later down the line, as instances of this class are being used as values of a HashMap. I have narrowed down the issue to being caused by the toString method, and when I remove it, Instance of 'Contact' is then printed out, as desired. What is the best way to handle this?

// Method in controller, triggered by onTap
Contact contact = Contact();
print(contact);
You created a new instance of Contact with no arguments that's why all the value of Contact will be null.
To assign a value there are two solutions:
1. Inside from class itself:
class Contact {
String name = 'John doe';
String relationship = 'Brother';
String phoneNo = '1234567890';
#override
String toString() {
print("""{
Name: $name,
Relation: $relationship,
Phone: $phoneNo
}""");
}
}
2.From outside of Class
for that, you have to initiate Constructor in your class
class Contact {
String name;
String relationship;
String phoneNo;
Contact(this.name, this.relationship, this.phoneNo);
//You can also choose between named parameters and positional parameters
// For named parameters Contact({this.name, and so on....})
#override
String toString() => """{
Name: $name,
Relation: $relationship,
Phone: $phoneNo
}""";
}
in this scenario you have to pass values where you create instance of class as shown here:
Contact contact = Contact('John Doe', 'brother', '123456789');
print(contact);

Related

Constructor Optional Params

Is there a way to set a constructor optional param?
I mean something like:
User.fromData(this._name,
this._email,
this._token,
this._refreshToken,
this._createdAt,
this._expiresAt,
this._isValid,
{this.id});
It indicates that
Named option parameters can't start with an underscore.
But I need this field as private, so, I'm lost now.
This is a more general answer for future viewers.
Positional optional parameters
Wrap the optional parameter with [ ] square brackets.
class User {
String name;
int age;
String home;
User(this.name, this.age, [this.home = 'Earth']);
}
User user1 = User('Bob', 34);
User user2 = User('Bob', 34, 'Mars');
Optional parameters need to be nullable if you don't provide a default value:
class User {
String name;
int age;
String? home; // <-- Nullable
User(this.name, this.age, [this.home]);
}
Named optional parameters
Wrap the optional parameter with { } curly braces.
class User {
String name;
int age;
String home;
User(this.name, this.age, {this.home = 'Earth'});
}
User user1 = User('Bob', 34);
User user2 = User('Bob', 34, home: 'Mars');
The default for home is "Earth", but like before, if you don't provide a default then you need to change String home to String? home.
Private fields
If you need private fields then you can use [] square brackets:
class User {
int? _id;
User([this._id]);
}
User user = User(3);
or do as the accepted answer says and use an initializer list:
class User {
int? _id;
User({int? id})
: _id = id;
}
User user = User(id: 3);
Named required parameters
Named parameters are optional by default, but if you want to make them required, then you can use the required keyword:
class User {
final String name;
final int age;
final String home;
User({
required this.name,
required this.age,
this.home = 'Earth',
});
}
User user1 = User(name: 'Bob', age: 34);
User user2 = User(name: 'Bob', age: 34, home: 'Mars');
You need to use a simple parameter and initialize your private field in initializer list.
class User {
final String _id;
final String _name;
User.fromData(this._name, {required String id})
: _id = id;
}
In addition to great Suragch's answer I wanted to mention required word. You can use it for multiple constructor or function named parameters to specify required ones.
class User {
int _id;
String _firstName;
String _lastName;
User({required int id, String firstName = "", String lastName})
: _id = id, // required parameter
_firstName = firstName, // optional parameter with default value ""
_lastName = lastName; // optional parameter without default value
}
User user1 = User(id: 1);
User user2 = User(id: 2, firstName: "John");
User user3 = User(id: 3, lastName: "Snow");
Related Dart docs here.
For Dart version <= 2.10 #required is an annotation and used with the # prefix.

Grails: HIbernate-filter - Adding filter on mapped class column

I want to use grails hibernate filter plugin to add a filter on of my domain class.
http://grails.org/plugin/hibernate-filter
Domain classes:
class Movie {
String name
String genre
String yearOfRelease
boolean deleted
}
class EditRequest {
String reason
String requester
Date requestDate
String status //can be 'PENDING', 'ONHOLD', OR 'COMPLETE'
static belongsTo = [
movie: Movie,
requester: User
]
}
There could be multiple edit request for a movie.
I have an API where I need to display all edit requests for all non-deleted movies.
How do I add hibernateFilter for non-deleted movies in my EditRequest domain class
I tried below in my EditRequest class, but non of them works.
1.
static hibernateFilters = {
deletedMovieFilter(condition:'deleted=false', default:true)
deletedMovieFilter(collection:'movie', default: true)
}
2.
static hibernateFilters = {
deletedMovieFilter(condition: 'deleted = false')
deletedMovieFilter(collection: 'movie', joinTable: true)
}

FreeMarker: how to get value of private attribute, not of public "get" method

I am trying to get the value of private field (attribute) without using "get" method even when this method exists.
Is it possible?
I created several examples following Freemarker get-method without "get":
Example 1: Successfully use "get" method for "private" field
Class:
public class MyClass {
private String myField = "TestA";
public String getMyField() { return "from method " + myField; }
}
Template: Test:${myObject.myField}
BeansWrapper config:
bw.setExposeFields(true);
// bw.setExposureLevel(BeansWrapper.EXPOSE_NOTHING);
Output: "Test:from method TestA"
Example 2: Successfully get value of "public" field
Class:
public class MyClass {
public String myField = "TestA";
public String getMyField() { return "from method " + myField; }
}
Template: Test:${myObject.myField}
BeansWrapper config:
bw.setExposeFields(true);
bw.setExposureLevel(BeansWrapper.EXPOSE_NOTHING);
Output: "Test:TestA"
Example 3: Can't get value of "private" field
Class:
public class MyClass {
private String myField = "TestA";
public String getMyField() { return "from method " + myField; }
}
Template: Test:${myObject.myField}
BeansWrapper config:
bw.setExposeFields(true);
bw.setExposureLevel(BeansWrapper.EXPOSE_NOTHING);
Output: Exception "The following has evaluated to null or missing: ==> myClass.myField"
None of the out-of-the-box ObjectWrapper-s (like BeansWrapper) allows reading private members. OTOH you can implement your own ObjectWrapper or extend an existing one (like BeansWrapper).

Grails: Legacy DB - Record with composite Id won't update

I'm having problems trying to update a record on a Grails 2.3.7 Project
I don't want to modify the fields that are part of the composite Id, I just want to update the other fields.
Just one class, few properties, but every time I try to update, it throws me the "not unique error" when this lines runs:
personInstance.validate()
if (personInstance.hasErrors()) {
respond personInstance.errors, view:'create'
return
}
My class looks like this:
class Person implements Serializable {
static constraints = {
name(unique: lastName)
}
static mapping = {
id generator: 'assigned'
id composite: ["name", "lastName"]
}
//Override equals and hashcode methods
boolean equals(other) {
if (!(other instanceof Person)) {
return false
}
other.name == name && other.lastName == lastName
}
int hashCode() {
def builder = new HashCodeBuilder()
builder.append name
builder.append lastName
builder.toHashCode()
}
String name
String lastName
String description
}
And the controller action:
def update() {
def personInstance = Person.get(new Person(name:params.name, lastName:params.lastName))
personInstance.properties = params
personInstance.validate()
if (personInstance.hasErrors()) {
respond personInstance.errors, view:'create'
return
}
personInstance.save flush:true
request.withFormat {/*etc...*/}
}
When I use validate(), it throws me a Grails unique key error, when I avoid validation its a BD not unique PK error.
Is like Grails didn't know if I want to do an insert or an update when I personInstance.validate().
Is there a way to manage this in a correct way that I'm not seeing?
Or am I forced to avoid validation?
am I doing something wrong?
Thanks in advance.
I believe the GORM mapping DSL expects just one id definition. Try combining your two id lines into just this one:
id generator: 'assigned', composite: ["name", "lastName"]
Also, in addition to implementing Serializable, your domain class should override equals and hashCode, as described under "Composite Primary Keys" here: http://grails.org/doc/latest/guide/single.html#identity

Why is my Groovy object initializer failing to set the property?

I have a Groovy class like so:
class Person {
String firstName
String lastName
Status status = StatusEnum.ACTIVE
}
And I'm creating an instance of it with an object initializer:
def person = new Person(
firstName: "Bob", lastName: "Yelo", status: StatusEnum.INACTIVE)
However, this doesn't modify the person's status and it remains as ACTIVE. I have to explicitly declare it:
person.status = StatusEnum.INACTIVE
Which properly sets the status. Does anyone know why I have to explicitly set it?
I'm guessing it's having something to do with the type of the field being Status rather than StatusEnum?
Declaring it like this worked as you're suggesting it should groovy console:
enum StatusEnum {
ACTIVE, INACTIVE
}
class Person {
String firstName
String lastName
StatusEnum status = StatusEnum.ACTIVE
}
def person = new Person(firstName: "Bob", lastName: "Yelo", status: StatusEnum.INACTIVE)
assert StatusEnum.INACTIVE == person.status

Resources