I'm trying to pass the value "1" into a Grails tag. However, it turns out to be an integer value of 49 - the ascii value for "1". How do I convert this to the proper value in Groovy?
Actually, there's a "toInteger()" function on a String.
To add to Jack BeNimble's comment, if you are using 1.2 (release of which is imminent), you also have null-safe converters to int (i.e. params.int('value'), which will do
From Release Notes.
Convenient, null safe converters in params and tag attributes
New convenience methods have been added to the params object and tag attrs objects that allow the easy, exception safe and null safe conversion of parameters to common types:
def total = params.int('total')
There are methods for all the common base types such as int#, #long#, #boolean and so on. There is a special converter called list that always returns a list for cases when dealing with one or many parameters of the same name:
def names = params.list('names')
Related
I was working through some code, and noticed:
return new Uri(host: server, path: apiPath, query: query, queryParameters: queryParams);
This code is executed regularly throughout the application, and the only difference was queryParams. So i printed it out:
{Id:[1234], enabled:false}
shows it is a key:value set of: Id:List, enabled:boolean.
The stack trace i get is:
which shows the map and then the trace. #6 points to the above line.
It is looking at false... something with iterating false is what breaks this.
When dealing with the URI and query parameters, it is looking for numerics, lists, and strings but not booleans. In order to resolve this and allow it to function correctly, you will need to do:
{"enabled": false.toString()}
// or
{"enabled": "false"}
and the uri class will set the query parameter accordingly.
The Uri class is located in core library for Dart. When we are using it, we are passing in the created Uri object into an action for a client class,
Client client = new BrowserClient();
which accepts the url as a part of the parameters.
While looking at the errors above though, the Uri class ultimately is unable to properly parse a false value to an accepted value.
When looking at the Code Docs for Uri as per the Dart languages: https://api.dartlang.org/dev/1.25.0-dev.7.0/dart-core/Uri/Uri.html
The query component is set through either query or queryParameters. When query is used, the provided string should be a valid URI query, but invalid characters, other than general delimiters, will be escaped if necessary. When queryParameters is used the query is built from the provided map. Each key and value in the map is percent-encoded and joined using equal and ampersand characters. A value in the map must be either a string, or an Iterable of strings, where the latter corresponds to multiple values for the same key.
Which makes sense to say all values must be String or an Iterable of Strings. The only thing which I cant figure out is that in Dartpad, true and false have toString functions, and yet you can also pass numerics in there.
The only conclusion is that while it accepts Strings and Iterables of Strings, it will also parse ints and other numerics because they will explicitly check for that type as it is common to see in URI.
One would think that the URI would understand booleans since those are also common place, but that is yet to be seen since I cant take an explicit look at the source code for dartlang. I did however manage to look at the source code for it and narrowed it down. writeComponent points to _Uri._uriEncode but when looking at that function, there is no code as much as just a definition.
HTH.
All values coming from a web form are string. I have a class named Announcement which has a field kind and its data type is integer. On the model class I define an enum
enum kind: {
event: 1,
feature: 2
}
About mass assignment I have done it, no problem in general. The problem is when I'm doing this it will complain about '1' is not a valid kind because it's a string not an integer.
announcement=Announcement.new(announcement_params)
Is there any solution for this problem except manually set the value for the field?
Thank you
The answer just come to my mind, this is what i do to solve the problem
kind=params[:announcement][:kind].to_i
params[:announcement].delete(:kind)
params[:announcement].merge(kind: kind)
Get the kind param and convert it to an integer
Remove the kind which is a string from the params
Merge the new kind to the params
And the last is white listing parameters for mass assignment
Thank you #uzaif
You can redefine the setter for the kind attribute in your Announcement model, like this:
# app/models/announcement.rb
def kind=(value)
super(value.to_i)
# or
# super(Integer(value))
end
This converts the given value to integer first and then calls the original method defined by the enum. Note however, that to_i will convert anything, even non-numbers or nils - these will be converted to 0. So I'd advise to either never use 0 among your defined enum values or to use the Integer(value) form, which will raise an exception on non-numbers or nils.
The setter allows mass assignment again:
Announcement.new(kind: '1') # should be OK
Is there an easy way to get a default value from an Erlang record definition? Suppose I have something like this:
-record(specialfield, {
raw = <<"default">> :: string()
}).
I would like to have some way to retrieve the default value of the raw field. Something like this would be very simple:
#specialfield.raw % => <<"default">>
This is not possible. I would need to instantiate a record in order to get the default value:
Afield = #specialfield{}
DefaultValue = Afeild#specialfield.raw
DefaultValue % => <<"default">>
Is there an easier way of doing this? I seems like there should be some way to retrieve the default value without having to create an instance of the record.
How about:
raw_default() -> <<"default">>.
-record(specialfield, { raw = raw_default() }).
And now you have a function with the default in it. This will be extremely fast since it is a function call to a constant value. If this is also too slow, enable inlining.
Constructing an empty record and accessing one field can be done on one line:
(#specialfield{})#specialfield.raw.
Take a look at erlang - records, search section "11.8".
There's not much special about records - they're just a tuple at runtime. So to get the field raw from the tuple of default values that is the internal representation of #specialfield{} you would use:
element(#specialfield.raw, #specialfield{}).
In this case, #specialfield.raw is the index of the value for raw in the #specialfield tuple. When you pass in specialfield that resolves to a tuple in the form {specialfield, <<"default">>}.
I have this code in my controller:
def cols = grailsApplication.getDomainClass('com.archie.Build').persistentProperties.collect {it.name}
The code above will allow me to list all the property names I have in Build class. Now, I would like to include also the properties data type, ie. boolean, String etc...
Somewhat like the output is:
[floorType:String, floorWidth:Float, ......]
Maybe not exactly like that, or maybe similar, but as long as I can return their data type. Can someone help? Thank you.
Each entry in persistentProperties is a GrailsDomainClassProperty, and this provides access to the type of the property as a Class object:
def props = [:]
grailsApplication.getDomainClass('com.archie.Build'
).persistentProperties.each {
props[it.name] = it.type.name
}
Or just pass the persistentProperties array itself through to the GSP, then extract .name and .type there.
You may also wish to consider using constrainedProperties instead of/in addition to the persistentProperties. The constrainedProperties map lists only those properties that are mentioned in the domain class constraints block, but the iterator over this map is guaranteed to return the properties in the order they are listed in the constraints. This is how the default scaffolding operates, as I'm not aware of any way to control the order of the persistentProperties array.
In my jsp page I have a form (in struts2) in which I try to assign the size of the ArrayList data to the Vector testVector using hidden tag after submitting the form, but I still get the size of testVector equal to 0.
<s:hidden name="testVector.size" value="%{data.size}" />
I have created setters and getters for data and testVector in my Action class.
private Vector<String> testVector = new Vector<String>();
private ArrayList<String> data = new ArrayList<String>();
private String testName; // a field for testing the form.
// getters and setters of testVector and data
I supposed that this should work because Vector has a public setter setSize(int size).For the other field "testName" it was well submitted.. So am I have a problem in syntax?
Thank you a lot.
You should not be using a Vector. Be aware that OGNL does not work the same from a requests as it does when rendering a JSP for security reasons, it is simply too powerful. You should just set bean properties, collections, arrays and built in types from the request (type converters ignored).
From the request in this case it thinks are are trying to put values into the vector. I think it will create a new string put it into the Vector and then try to set the size of string (which will not work because that method does not exist).
To confirm this I tried to do what you are saying and the log states:
WARNING: Error setting expression 'testVector.size' with value '[Ljava.lang.String;#5c7b2d2f'
ognl.OgnlException: Error converting given String values for Collection. [ognl.NoSuchPropertyException: java.lang.String.size]
If you want this behaviour you will need to create a second method such as setSize() within your action which then goes about modifying the vector size. This I don't think is a very good thing to expose to the outside world, what if someone called your action many times passing in a huge number?