Grails - Bind parameter to command object field of a different name - grails

If I have a command object SomeClassCommand with a String field someField but want to bind data from a parameter params.otherField, how do I go about doing that? Is there an annotation I can put in the command object?

Actually there is a horrendous work around which defies the purpose of auto binding in your case.
def map = [:]
map.someField = params.otherField
//plus set all the other params to map
map << params
def commandObj = new SomeCommandObj()
//Explicitly bind map to command object
bindData(commandObj, map)
It really is horrendous, because you are doing extra work only to bind data. You could have directly set values to Command Object.
I would suggest either to change the command object field name or the parameter field name, which ever is controllable. AFAIK there is no annotation available unless you have your own utility to do such.

Related

Update Nova resource with a empty string as default for field

I have an existing data model that has a unique indexed string field that defaults to an empty string.
I added an $attributes property to the model to default it to an empty string when creating a new object. That works just fine.
However when updating the object and the field remains empty, it will fail since the field is returned as null and the DB field is not nullable. I am not sure of the impact of making that field nullable(). Too much code to dig through so I can't change it.
I am thinking I can observe for an event, and change the value from null to empty string there, but I would rather take care of this in Nova.
Is there anyway to tell Nova an empty field should be saved as an empty string?
Short version: no.
Long version:
This cannot be set in Nova. An empty string will be passed as null in the HTTP request. This behaviour is part of Laravel's core. The only way to make sure it isn't passed as an empty string from Nova is to put form validation on it and make it a required field.
If you don't mind changing code on the Laravel app level, you can disable this behaviour by removing the ConvertEmptyStringsToNull middleware in your app's Kernel.
/app/Http/Kernel.php
protected $middleware = [
...
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, // remove this line
];
However, if the DB field isn't nullable, the field has to have a value anyway right? I'd suggest putting an accessor on the model to check for null values:
public function setMyFieldAttribute($val)
{
$this->attributes['my_field'] = $val ?? '';
}
Or, if you want to be really certain it always has a value, add an observer for the saving event (as you already mentioned), and make sure the field has a value before the data is actually saved.

For each in by reference or value

I have the following code:
dim key
for each key in Request.Querystring
'do something
key = sanitized_param(key)
next
My question for you classic-asp connoisseur, does classic-asp, or asp in general, pass the variables as references(memory), or by value? Trying to figure out if I sanitize the key variable and pass it back to itself, is it just "alive" for that loop, or does the new value get passed to the original QueryString?
Request.QueryString retrieves the query string parameters by value from the page headers.
You can only make changes to a query string once its been retrieved via Request.QueryString, but you can't make changes directly to Request.QueryString as it's read-only (If you could make changes you would presumably use Response.QueryString, but this isn't a valid response command).
I'm guessing you're trying to sanitize all your query strings in one go? This isn't really possible or indeed necessary. You would typically sanitize a query string as and when you request it:
Response.Write(sanitized_param(Request.QueryString("myQS")))
Or to assign the query string to a variable first then sanitize it:
Dim myQS
myQS = Request.QueryString("myQS")
myQS = sanitized_param(myQS)
' or
myQS = sanitized_param(Request.QueryString("myQS"))
Once the query string has been assigned to a variable and sanitized you're able to reference that variable as often as you like without having to pass it to your sanitize function again.
Also, your example code doesn't make much sense. The key value in your for each loop is referencing just the names of your query strings and not their values. If Response.QueryString was a valid ASP command you would do:
Response.QueryString(key) = sanitized_param(Request.QueryString(key))
But again, this isn't possible.
EDIT: This solution might be what you're looking for:
Create a dictionary object, call it "QueryString" for example. Loop through all your query strings and add a sanitized version to the dictionary object.
Dim QueryString : Set QueryString = Server.CreateObject("Scripting.Dictionary")
For Each Item In Request.QueryString
QueryString.Add Item,sanitized_param(Request.QueryString(Item))
next
Now, to retrieve a sanitized version of a query string just use:
QueryString.Item("query_string_name")
Or for the original unsanitized version you could still use:
Request.QueryString("query_string_name")
Just like Request.QueryString, the dictionary object is forgiving and won't return an error if you ask for a query string that doesn't exist.
You could also create a function for retrieving sanitized query strings, for example:
Function SanitizedQS(ByVal qsName)
SanitizedQS = sanitized_param(Request.QueryString(qsName))
End Function
And rather than using Request.QueryString("query_string_name") just use SanitizedQS("query_string_name").

How to update value in angular ui typeahead directive if no matching option is found

I've an array of objects containing title and salary which is used in typeahead directive.
I display department name and get entire object as value.
If none of the options match, I want user entered string to be converted to object still. Is there any way to update that?
This answer is pretty late, but I would just use ng-blur (to trap the end of the users input) along with a variable bound to typeahead-no-results. Then test if the variable is true in the method bound to ng-blur, and, if so, make an object out of the String supplied by the user and push it to your data source. Simple example found here.

Is it possible to build a grails config property key programmatically?

When accessing a Config.groovy property using grailsApplication.config.myapp.something
Is it possible to build the property key programmatically somehow? e.g. grailsApplication.config.myapp. + somethingVar.toString()
Groovy allows you to use GString expressions for property accesses, so
grailsApplication.config.myapp."${somethingVar}"
will do what you want as long as somethingVar doesn't contain any dots. If you have a variable that contains the whole config key including the dots then you can use flatConfig:
def key = "myapp.something"
def value = grailsApplication.flatConfig."${key}"
or if the variable is part of the "path" but not the whole:
def key = "some.thing"
def value = grailsApplication.flatConfig."myapp.${key}" // gives myapp.some.thing
or you can avoid the flatConfig by using a trick with inject
def key = "some.thing"
def value = key.split(/\./).inject(grailsApplication.config.myapp) { co, part ->
co."${part}"
}
The inject method calls the closure once for each item in the array we're iterating over, each time passing in the value that the last iteration returned (I've called it co as it will be a ConfigObject) and the value for this iteration (part). The overall result of inject is the value returned by the last iteration.

Determine Data Type

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.

Resources