Should toString() method be used to display object in Grails? - grails

I have a simple Address domain object that has the following string fields: line1, line2, city, state, zipCode. I'd like to setup the toString() method to display a formatted string skipping any fields that are null.
For example, an Address that does not have a line2 should be displayed as: , , (e.g. "1234 My Street, Albuquerque, NM, 12345" rather than "1234 My Street, null, Albuquerque, NM, 12345").
Is there a slick way to do this in groovy other than the following? Also, since Grails generates code that uses the toString() to represent domain objects on the web pages, should I continue to use toString() for display purposes or should I be making a gsp template or something to display and format domain object info? If toString() is just for getting started and should not be used for display purposes long term, then this issue goes away.
public String toString() {
String str = null
if (line1) {
str += line1
}
if (line2) {
if (string.empty == false) {
str += ", "
}
str += line2
}

"${number} ${street} ${extended?:''}, ${city}, ${state}, ${zipcode}".replace(' ,',',')
or
["$number $street",extended,city,state,zipcode].minus(null).join(', ')
Where should you do it is a design decision, is the formatted address gonna be printed in a several different places? If so, you could make a taglib. Generally, I like to keep data formatting responsibilities away from domain classes.

Related

Print detailed structure / type information of a variable's value

I wonder, if a dart or flutter method exists, which returns complete type information about the structure of a variable's value as a string.
E.g., if some print( someValue.toString() ); emits this
{"user":"userName","state":"valid"}
I don't know if it is a Map or a String.
But how do I get a string, which describes a variable's value / structure?
Something, that's like PHP's print_r(), which print stuff like this:
Array
(
[a] => Apfel
[b] => Banane
[c] => Array
(
[0] => x
[1] => y
[2] => z
)
)
There is nothing like print_r() available natively in Dart.
However, it would be possible to use the following functionalities to build e.g. a function like print_r() from PHP.
You can evaluate the type of someValue using runtimeType.
String someValueType = someValue.runtimeType.toString();
String someValueString = someValue.toString();
If you want to compare, you can also use is. More on that here.
Dart is a strongly typed language, which means that you could also enforce types (List a; String b), which makes a function like print_r() redundant for Dart.
If it is about server-side code you can use reflection to create a function that produces such an output for every value.
If it is about your own classes, you can implement toString() to make the objects render themselves this way when they are printed
class Person {
Foo(this.firstName, this.lastName);
String firstName;
String lastName;
#override
String toString() => '''
firstName: $firstName
lastName: $lastName
''';
}
print(new Person('John', 'Doe'));
Best way to do is
print(”$someValue“);
It will return a structured string which similar to JSON.

how to get data from database to controller in grails 3

i am new in grails 3 and i wanted to know that how we can get the values from the database to the controller
i tried
def std = Students.get(1)
but it returns only the id not the actual value
plzzzz can anyone help me
You could also do:
def std = Students.findById(id);
If you are printing the result of get, the toString() default methods is call if you haven't create your own. Then if you do:
def std = Students.get(1)
println std
Students: 1 will be printed
You can implement your toString() method as:
Students{
String name
String toString(){
name
}
}
In this case the result of println will be its name.
If you want to print all fields of the object just do
println std.dump()

Store phoneNumbers in Grails Domain Classes?

I want to store phone numbers in Grails domain classes. I am not sure what is the best way of doing this. Storing as int does not seems to be a good idea because leading zero is impossible for that.
What is the best way to store and validate phone numbers in Grails domain classes?
I would store phone as a String - nullable and blank too. For display purposes, simply provide your own tag in grails's tablib package.
For example, with a property inside some domain class like this:
String phone
And a taglib class like this:
class MyTagLib {
static defaultEncodeAs = [taglib:'html']
def phone334 = { attrs ->
String phone = attrs.phone
def formatted =
"(".concat(phone.substring(0, 3)).concat(") ")
.concat(phone.substring(3, 6)).concat("-").concat(phone.substring(6))
out << formatted
}
}
and a usage like this inside a gsp:
<g:phone334 phone="${theInstance.phone}" />
Then if phone = '4165557799', the output would be displayed like this: (416) 555-7799.
You can build as many formatters as you want; for example, if your number is 011218213334488 and you need it to look like +(218) 21 333 4488, simply build a formatter for that depending on the length and/or the pattern detected in the input.
You can also build simple validators right there too to make sure for example that all characters are made up of digits and parentheses and dashes, but I don't think taglibs are the right place for that - perform a bit of filtering and validation as suggested in the other posts before getting to displaying what should be correct input material.
You could most probably use matches constraint and store phone numbers as String as there is no predefined constraints for phone numbers. There in matches you can use any regex pattern required according to your needs.
static constraints = {
phone(matches: "^(?:0091|\\+91|0)[7-9][0-9]{9}$")
}
The above regex will work like :-
Begins with 0, +91 or 0091
Followed by a 7-9
Followed by exactly 9 numbers
Must match entire input
You can change it according to your needs.
You can store the phone number as string. To validate the phone number you can use google phone number java library to validate international numbers. Or more easily you can use this grails plugin in your code: https://github.com/ataylor284/grails-phonenumbers . Here is a sample from the plugin home page.
class MyDomain {
String phoneNumber
static constraints = {
phoneNumber(phoneNumber: true)
}
}
Edit:
To validate the number if it is not blank you have to define your custom constraint class which extends PhoneNumberConstraint class.
class CustomPhoneNumberConstraint extends PhoneNumberConstraint{
#Override
protected void processValidate(target, propertyValue, Errors errors) {
//check if phone number is blank
if (propertyValue instanceof String && GrailsStringUtils.isBlank((String)propertyValue)) {
if (!blank) {
super.processValidate(target,propertyValue, errors)
}
}
return true
}
}

Groovy Dynamic List Interaction

I am using an older version of grails (1.1.1) and I am working on a legacy application for a government client.
Here is my question (in psuedo form):
I have a domain that is a Book. It has a sub domain of type Author associated with it (1:many relationship). The Author domain has a firstName and lastName field.
def c = Book.createCriteria()
def booklist = c.listDistinct {
author {
order('lastName', 'asc')
order('firstName', 'asc')
}
}
Let's say I have a list of fields I want to use for an excel export later. This list has both the author domain call and the title of the column I want to use.
Map fields = ['author.lastName' : 'Last Name', 'author.firstName', 'First Name']
How can I dynamically call the following code--
booklist.eachWithIndex(){
key, value ->
println key.fields
}
The intent is that I can create my Map of fields and use a loop to display all data quickly without having to type all of the fields by hand.
Note - The period in the string 'author.lastName' throws an error when trying to output key['author.lastName'] too.
I don't recall the version of Groovy that came with Grails 1.1, but there are a number of language constructs to do things like this. If it's an old version, some things may not be available - so your mileage may vary.
Map keys can be referenced with quotes strings, e.g.
def map = [:]
map."person.name" = "Bob"
The above will have a key of person.name in the map.
Maps can contain anything, including mixed types in Groovy - so you really just need to work around string escapes or other special cases if you are using more complex keys.
You can also use a GString in the above
def map = [:]
def prop = "person.name"
map."${prop}" = "Bob"
You can also get a map of property/value off of a class dynamically by the properties field on it. E.g.:
class Person { String name;String location; }
def bob = new Person(name:'Bob', location:'The City')
def properties = bob.properties
properties.each { println it }

ASP.NET MVC: dealing with Version field

I have a versioned model:
public class VersionedModel
{
public Binary Version { get; set; }
}
Rendered using
<%= Html.Hidden("Version") %>
it gives:
<input id="Version" name="Version" type="hidden" value=""AQID"" />
that looks a bit strange. Any way, when the form submitted, the Version field is always null.
public ActionResult VersionedUpdate(VersionedModel data)
{
...
}
How can I pass Version over the wire?
EDIT:
A naive solution is:
public ActionResult VersionedUpdate(VersionedModel data)
{
data.Version = GetBinaryValue("Version");
}
private Binary GetBinaryValue(string name)
{
return new Binary(Convert.FromBase64String(this.Request[name].Replace("\"", "")));
}
Related posts I found.
Link
Suggests to turn 'Binary Version' into 'byte[] Version', but some commenter noticed:
The problem with this approach is that
it doesn't work if you want to use the
Table.Attach(modified, original)
overload, such as when you are using a
disconnected data context.
Link
Suggests a solution similar to my 'naive solution'
public static string TimestampToString(this System.Data.Linq.Binary binary)
{ ... }
public static System.Data.Linq.Binary StringToTimestamp(this string s)
{ ... }
http://msdn.microsoft.com/en-us/library/system.data.linq.binary.aspx
If you are using ASP.Net and use the
SQL Server "timestamp" datatype for
concurrency, you may want to convert
the "timestamp" value into a string so
you can store it (e.g., on a web
page). When LINQ to SQL retrieves a
"timestamp" from SQL Server, it stores
it in a Binary class instance. So you
essentially need to convert the Binary
instance to a string and then be able
to convert the string to an equivalent
Binary instance.
The code below provides two extension
methods to do this. You can remove the
"this" before the first parameter if
you prefer them to be ordinary static
methods. The conversion to base 64 is
a precaution to ensure that the
resultant string contains only
displayable characters and no escape
characters.
public static string ConvertRowVersionToString(this Binary rowVersion) {
return Convert.ToBase64String(rowVersion.ToArray());
}
public static Binary ConvertStringToRowVersion(this string rowVersion) {
return new Binary(Convert.FromBase64String(rowVersion));
}
I think the problem with not seeing it in the bound model on form submission is that there is no Convert.ToBinary() method available to the model binary to restructure the data from a string to it's binary representation. If you want to do this, I think that you'll need to convert the value by hand. I'm going to guess that the value you are seeing is the Base64 encoding of the binary value -- the output of Binary.ToString(). In that case, you'll need to convert it back from Base64 to a byte array and pass that to the Binary() constructor to reconstitute the value.
Have you thought about caching the object server-side, instead? This could be a little tricky as well as you have to detach the object from the data context (I'm assuming LINQ) or you wouldn't be able to reattach it to a different data context. This blog entry may be helpful if you decide to go that route.
You may need to use binding to get a strongly-typed parameter to your action method.
Try rendering using:
<%=Html.Hidden("VersionModel.Version")%>
And defining your action method signature as:
public ActionResult VersionedUpdate([Bind(Prefix="VersionModel")] VersionedModel data)
{
...
}
This post http://forums.asp.net/p/1401113/3032737.aspx#3032737 suggests to use
LinqBinaryModelBinder from http://aspnet.codeplex.com/SourceControl/changeset/view/21528#338524.
Once registered
protected void Application_Start()
{
ModelBinders.Binders.Add(typeof(Binary), new LinqBinaryModelBinder());
}
the binder will automatically deserialize Version field
public ActionResult VersionedUpdate(VersionedModel data)
{ ... }
rendered this way:
<%= Html.Hidden("Version") %>
(See also http://stephenwalther.com/blog/archive/2009/02/25/asp.net-mvc-tip-49-use-the-linqbinarymodelbinder-in-your.aspx)
There are many ways like here
byte[] b = BitConverter.GetBytes(DateTime.Now.Ticks);//new byte [(DateTime.Now).Ticks];
_store.Version = new System.Data.Linq.Binary(b)
(make sure you bind exclude your version),
But the best way is to let the DB handle it...
There are many ways like here
byte[] b = BitConverter.GetBytes(DateTime.Now.Ticks);//new byte [(DateTime.Now).Ticks]; _store.Version = new System.Data.Linq.Binary(b)
(make sure you bind exclude your version),
But the best way is to let the DB handle it...

Resources