Checking if a collection is null or empty in Groovy - grails

I need to perform a null or empty check on a collection; I think that !members?.empty is incorrect. Is there a groovier way to write the following?
if (members && !members.empty) {
// Some Work
}

There is indeed a Groovier Way.
if (members) {
//Some work
}
does everything if members is a collection. Null check as well as empty check (Empty collections are coerced to false). Hail Groovy Truth. :)

FYI this kind of code works (you can find it ugly, it is your right :) ) :
def list = null
list.each { println it }
soSomething()
In other words, this code has null/empty checks both useless:
if (members && !members.empty) {
members.each { doAnotherThing it }
}
def doAnotherThing(def member) {
// Some work
}

!members.find()
I think now the best way to solve this issue is code above. It works since Groovy 1.8.1 http://docs.groovy-lang.org/docs/next/html/groovy-jdk/java/util/Collection.html#find(). Examples:
def lst1 = []
assert !lst1.find()
def lst2 = [null]
assert !lst2.find()
def lst3 = [null,2,null]
assert lst3.find()
def lst4 = [null,null,null]
assert !lst4.find()
def lst5 = [null, 0, 0.0, false, '', [], 42, 43]
assert lst5.find() == 42
def lst6 = null;
assert !lst6.find()

Related

Grails 3 Cookie Plugin - return Null

i am trying to use cookie in grails 3.
i tried this plugin but i don't know why its not work at all..
cookieService.setCookie('username', customer?.email)
and i use this code for call it from gsp
<g:cookie name="username"/>
i also tried this way..
def cokusername = cookieService.setCookie('username', customer?.email)
println "cookieService.getCookie('username') = "+cookieService.getCookie('username')
redirect(controller: "toko",cokusername: cokusername)
and this is in my tokoController.groovy index :
def index={
def toko = CifLogo.executeQuery("from CifLogo order by rand()",[max: 10])
// def itemRandom = Item.executeQuery("from Item where cif = :cif order by rand()",[max:12,cif:cif])
def awdf = cookieService.getCookie('username')
println "awdf = "+awdf
println "cokusername = "+params.cokusername
[tokoList:toko,cokusername:awdf]
}
i have no idea to retrieve my cookie. :(
update
def index(){
def toko = CifLogo.executeQuery("from CifLogo order by rand()",[max: 10])
// def itemRandom = Item.executeQuery("from Item where cif = :cif order by rand()",[max:12,cif:cif])
def awdf = cookieService.getCookie('username')
println "awdf = "+awdf
println "cokusername = "+params.cokusername
[tokoList:toko,cokusername:awdf]
}
i tried to print cookie like this..
def awdf = request.getCookie('username')
println "awdf = "+awdf
println "cokusername = "+params.cokusername
request.cookies.each { println "${it.name} == ${it.value}" }
and this is what the result
From what I can see this line:
redirect(controller: "toko",cokusername: cokusername)
Should be:
redirect(controller: "toko",params:[cokusername: cokusername])
Also actions using closures in grails 3 will have undesired results. You should change to methods. Hence this line:
def index={
SHould be:
def index(){
Apart from this it seems the cookieService code should work fine, so I can only assume its being caused my the closure index that should be a method.
Another thing could be the fact that you are doing a redirect, which will clear the request and not persist any cookies that were set before the redirect
I don't know why, but maybe it's a bug.
i use this code to setCookie
cookieService.setCookie(name:"username", value: customer?.email, maxAge: 24*60*60, path: "/")
after read this code.
and i cannot deleteCookie with this code.
cookieService.deleteCookie(cookieService.findCookie("username"))
because when i print cookieService.findCookie("username") it returns javax.servlet.http.Cookie#78cbf320
and method deleteCookie(Cookie cookie) from this link
so i think it mustbe deleted.
but still availlable.
so i can answer this question about setCookie not deleteCookie
i also tried this way to delete cookie..but still failed.
CookieService.setCookie(name:"username", value: "", maxAge: 0, path: "/")

executeUpdate() not updating on grails spock-integration testing

hi i am new to grails testing. Willing to do integration test as below but
problem is that executeUpdate() seems not updating the value
How to do integration testing for
executeUpdate('update query goes here') ??
Please help suggest me
Sample code is given for problem demo.
Thanks in advance.
def "for given merchantTier Id update merchantTier value"(){
setup:
def merchantTier = new MerchantTier(
value:1.11).save(flush: true) //it saves merchantTier
when:"when update with setProperty"
testData = editWithSetProperty(merchantTier.id) //id is passed
then:"it updates data and test is success"
merchantTier.value == 2.22
when:"executeUpdate query is used instead"
testData = editWithExecuteUpdate(merchantTier.id)// id is passed
then:"it does not update the data and test is failed"
merchantTier.value == 3.33
}
def editWithSetProperty(id) {
def merchantTier = MerchantTier.get(id.toLong())
merchantTier.setValue(2.22.toDouble())
}
def editWithExecuteUpdate(id) {
MerchantTier.executeUpdate('update MerchantTier mt set mt.value=:mrValue where mt.id=:mtId', [mrValue: 3.33.toDouble(), mtId: id.toLong()])
}
How to do integration testing for
executeUpdate('update query goes here') ??
as you are updating through executeUpdate you again need to fetch the object from database so try returning the fresh object fetched from database in editWithExecuteUpdate
def editWithExecuteUpdate(id) {
MerchantTier.executeUpdate('update MerchantTier mt set mt.value=:mrValue where mt.id=:mtId', [mrValue: 3.33.toDouble(), mtId: id.toLong()])
merchantTier = MerchantTier.get(id)
}
once done then you will have testData containing merchantTier object in when: clause
so in then: clause have
testData.value == 3.33
hope this make sense. Thanks
Edit - Additional Way
def editWithExecuteUpdate(id) {
def updatedRecords = MerchantTier.executeUpdate('update MerchantTier mt set mt.value=:mrValue where mt.id=:mtId', [mrValue: 3.33.toDouble(), mtId: id.toLong()])
return updatedRecords
}
so in then: clause have as due to executeUpdate only one row should be updated based on unique id and also fetch fresh object again and check the persisted value
testData == 1
def freshMerchantTier = MerchantTier.get(merchantTier.id)
freshMerchantTier.value == 3.33
Try this way once, please. Thanks

Is there a limit to how many association levels you can reference in a Where query?

This works:
def query = Idea.where {manager.id == id}
This doesn't work:
def query = Idea.where {manager.profile.riding.id == id}
How can I get around this?
Construction Idea.where and Idea.withCriteria are not self-sufficient and not reliable. Always use construction Idea.createCriteria().
def riding = Riding.get(id)
def results = Idea.createCriteria().list() {
manager{
profile{
eq('riding', riding)
}
}
}

why is groovy skipping the each statement

I have the following controller action in grails to determine if an item is in my shopping cart
def itemInCart(){
def cartHasItem = false
def product = Product.findOrCreateByPartNumberAndColor(params.partNumber, params.color)
def cart = shoppingCartItems()
cart.each() { item ->
if (item['partInfo']['partNumber'] == params.partNumber && item['partInfo']['color']==params.color){
cartHasItem = true
}
}
render(cartHasItem)
}
I added an item to the cart
cart at the time of cart.each() is
[{partInfo={partNumber=69874, color=BLACK}, qty=1, price=16.99}]
params.partNumber = 69874
params.color = BLACK
The issue is that my code is completely skipping over the each() block. debug hits cart.each() { item -> and then goes streight to render
Looks like you want to use any instead of each here:
def cartHasItem = cart.any{ item ->
item['partInfo']['partNumber'] == params.partNumber && item['partInfo']['color']==params.color
}
I wanted to expand on #Dónal's comment on the question, to find out why each() vs each is different.
I've never used object.each() {}, instead I always use this form:
cart.each { item ->
// do work
}
However, I couldn't actually get each() to fail in this simple test:
def myfn() {
def items = [1,2,3]
def ret = false
items.each() {item -> if (item == 2) { ret = true }}
return ret
}
myfn()
==> true
I tried a more complicated version using a map to represent the data you are using, and a simple version just using
[[a:1, b:2, c:3]].each() { println it }
which always renders the item.
What version of groovy are you using?
I'm assuming your data is actually a list of maps here, your syntax for the item was more clojure, than groovy.

Grails query not inList

I'm writing a criteria to make a query, but I can't figure out how to negate an inList criteria...Is there a way to do something like:
def result = c {
not inList('id', ids)
}
Thanks
Your criteria should like this...
def ids = [1, 2, 3];
def c = Foo.createCriteria();
def results = c.list {
not {'in'("id",ids)}
}
The documentation can be found here. I believe this was just added in grails 2.+

Resources