Grails YAML list of maps - grails

In my Grails 3 application.yml, I'm defining a list of maps as follows:
tvoxx:
cfpApis:
-
url: http://cfp.devoxx.be/api/conferences
youtubeChannelId: UCCBVCTuk6uJrN3iFV_3vurg
-
url: http://cfp.devoxx.fr/api/conferences
-
url: http://cfp.devoxx.ma/api/conferences
youtubeChannelId: UC6vfGtsJr5RoBQBcHg24XQw
-
url: http://cfp.devoxx.co.uk/api/conferences
-
url: http://cfp.devoxx.pl/api/conferences
But when I try to load this config in my service using the following code, apiConfig is null:
def apiConfig = grailsApplication.config.getProperty("tvoxx.cfpApis")
I don't get any error when the application starts and my YAML code parses correctly on http://yaml-online-parser.appspot.com/ so I don't know what's wrong.

Just to confirm what we discussed on Slack.
Using grailsApplication.config.getProperty("tvoxx.cfpApis"), Grails will try to find value of type String and because your value is a Map null will be returned.
You have to explicitly tell what type you expect, using:
grailsApplication.config.getProperty("tvoxx.cfpApis", Map)
Other way is to use getAt() method, where object is returned, so you can use
grailsApplication.config.tvoxx.cfpApis to get the value.
First one may be better for .java and #CompileStatic but for standard .groovy class latter has easier syntax. Just watch out for keys which does not exist, because it will return empty ConfigObject instead of null, and for example ?.toString() method will result in 'ConfigObject#123123 instead of null

Related

unable to read messages from messages file in unit test

I want to read the error messages from messages file but I am unable to. What mistake am I making?
The code where I want to read the string from messages file is
Future { Ok(Json.toJson(JsonResultError(messagesApi("error.incorrectBodyType")(langs.availables(0))))) }
The messages file error.incorrectBodyType=Incorrect body type. Body type must be JSON
The messagesApi("error.incorrectBodyType") should return Incorrect body type. Body type must be JSON but it returns error.incorrectBodyType.
If I remove double quotes in messagesApi(error.incorrectBodyType) then the code doesn't compile
Update
I added a couple of debug prints and notice that the keys I am using in MessagesApi are not defined. I don't know why though as I have created them in messages file.
println("langs array"+langs.availables)
println("app.title"+messagesApi.isDefinedAt("app.title")(langs.availables(0)))
println("error"+messagesApi.isDefinedAt("error.incorrectBodyType")(langs.availables(0)))
prints
langs arrayList(Lang(en_GB))
app.titlefalse
errorfalse
Update 2
I might have found the issue but I don't know how to resolve it. Basically, I am running my test case without an instance of the Application. I am mocking messagesApi by calling stubMessagesApi() defined in Helpers.stubControllerComponents, If I run the same code using an Application eg class UserControllerFunctionalSpec extends PlaySpec with OneAppPerSuiteWithComponents then app.title and error are defined. It seems without an instance of Application, MessagesApi is not using the messages file.
I was able to solve the issue by creating a new instance of MessagesApi using DefaultMessagesApi
val messagesApi = new DefaultMessagesApi( //takes map of maps. the first is the language file, the 2nd is the map between message title and description
Map("en" -> //the language file
Map("error.incorrectBodyType" -> "Incorrect body type. Body type must be JSON") //map between message title and description
)
)
val controller = new UserController(mockUserRepository,mockControllerComponents,mockSilhouette,messagesApi,stubLangs())

Cannot convert value to bool : InvalidArgumentException

I am using cakephp 3.3 for my vod application and i want to insert data using following query:
$query=$notifications->query()->insert(['message' ,'status','user_id' ,'video_id' ,'notify_to' ,'notification_type'])
->values([
'message'=>'Congratulations! your video '.$video_name.' has been approved to be uploaded on MM2View by admin.',
'status'=>$status,
'user_id'=>$user_id[0]['users_id'],
'video_id'=>$id,
'notify_to'=>1,
'notification_type'=>3
])
->execute();
But i am getting
Cannot convert value to bool : InvalidArgumentException Error message. I have done some google related to this problem but did not find any correct solution.
Invalid argument exceptions are caused because of type mismatch in operations you written in the code.
Check your model class for the type you given and compare it with the code

getting error updating the sqlite

I am doing the project and I am structed in database path. I am using the sqlite database for storing. In this my problems is when I updating the table it showing the error. For database part I am using prewritten classes. I am calling that class method whenever I need. See below you can understand.
This below code is working fine
[DataCachingHelper updateTable:#"sendertable" data:dic3 where:#"MESSAGE_ID='1234'"];
but when I am sending the object to the "where", It showing some error.
[DataCachingHelper updateTable:#"sendertable" data:dic3 where:#"MESSAGE_ID=%#",#"hai"];
i am getting the error:
"too many arguments to methods call expected 3,have 4".
here MESSAGE_ID is VARCHAR TYPE
The issue is clear here. You can not pass string format because compiler compiles parameter before converting into string format. From your method declaration allowed parameters must be 3.
So compiler detect 4 parameter as you pass string with format.
Also in sqlite database for VARCHAR type field use double quotes for field values.
So your string should be like this:
NSString *whereClauseString = [NSString stringWithFormat:#"MESSAGE_ID = \"%#\"",#"hai"];
Or if value is pre known simply create string like this:
NSString *whereClauseString = #"MESSAGE_ID = \"hai\"";
And then use this string as third parameter for updateTable method:
[DataCachingHelper updateTable:#"sendertable" data:dic3 where:whereClauseString];
make this in two step.
NSString *strWhere=[NSString stringWithFormat:#"MESSAGE_ID='%#'",#"hai"];
[DataCachingHelper updateTable:#"sendertable" data:dic3 where:strWhere];

Strange behavior of gorm finder

In a controller I have this finder
User.findByEmail('test#test.com')
And works.
Works even if I write
User.findByEmail(null)
But if i write
User.findByEmail(session.email)
and session.email is not defined (ergo is null) it throw exception
groovy.lang.MissingMethodException: No signature of method: myapp.User.findByEmail() is applicable for argument types: () values: []
Is this behavior right?
If i evaluate "session.email" it give me null so I think it must work as it do when I write
User.findByEmail(null)
Even more strange....
If I run this code in groovy console:
import myapp.User
User.findByEmail(null)
It return a user that has null email but if I run the same code a second time it return
groovy.lang.MissingMethodException: No signature of method: myapp.User.findByEmail() is applicable for argument types: () values: []
You can't use standard findBySomething dynamic finders to search for null values, you need to use the findBySomethingIsNull version instead. Try
def user = (session.email ? User.findByEmail(session.email)
: User.findByEmailIsNull())
Note that even if User.findByEmail(null) worked correctly every time, it would not necessarily give you the correct results on all databases as a findBySomething(null) would translate to
WHERE something = null
in the underlying SQL query, and according to the SQL spec null is not equal to anything else (not even to null). You have to use something is null in SQL to match null values, which is what findBySomethingIsNull() translates to.
You could write a static utility method in the User class to gather this check into one place
public static User byOptEmail(val) {
if(val == null) {
return User.findByEmailIsNull()
}
User.findByEmail(val)
}
and then use User.byOptEmail(session.email) in your controllers.
Jeff Brown from grails nabble forum has identified my problem. It's a GORM bug. see jira
More info on this thread
This jira too
I tried with debugger and it looks it should be working, as you write. Maybe the groovy itself is a little bit confused here, try to help it this way:
User.findByEmail( session['email'] )

Beginner Groovy

I'm following the code examples in 'The Definitive Guide to Grails' by Graeme Keith Rocher, and have come across a rather unusual stumbling block.
Essentially, 2 domain classes exist - Bookmark & Tag.
Bookmark:
class Bookmark {
static hasMany = [tags:Tag]
URL url
String title
String notes
Date dateCreated = new Date()
}
Tag:
class Tag{
static belongsTo= Bookmark
Bookmark bookmark
String name
}
I'm instructed to launch the Grails Console (is this the same as the groovy console)and create a new object as follows.
def b = new Bookmark(url: new URL('http://grails.org/'), title:'Grails', notes:'Groovy')
This results in:
Result: Bookmark : null
According to the book, GORM automatically provides an implementation of an addTag method. So I code...
b.addTag( new Tag(name: 'grails'))
Only to get whammed with the error message:
Exception thrown: No such property: b for class: ConsoleScript1
groovy.lang.MissingPropertyException: No such property: b for class: ConsoleScript1 at ConsoleScript1.run(ConsoleScript1:2)
The author hasn't accounted for this in the book. I was wondering if anyone could help me out?
Thanks.
Are you reading the 1st edition of the book? If so it's quite outdated. The add* methods have been deprecated since 0.5. It was replaced by addTo* so do this instead:
b.addToTags( new Tag(name: 'grails'))
Assuming your code example shouldn't have Bookmarks defined twice (copy and paste error?) and Tag might look like this:
class Tag {
String name
}
The groovy console is not the same as the grails console. To access the grails console, type grails console in your application directory - you should get a Java GUI app. It's possible that the example will work then because grails add some stuff to the standard Groovy.
Also, your problem isn't the addTag method, but the item b that you defined which cannot be found. Try entering the whole script into the console at once and executing it, instead of executing it line by line.

Resources