Saturday 30 June 2012

JQuery $.on() function and the 'click' handler

So I am using the $.on() function to assign the 'click' event to one of my buttons, and on certain browsers things worked well, but on Firefox there was a problem, specifically the button would refresh.
My original code:


      self.init = function() { 
           $('.search-btn').on('click', function() {
                var searchTerm = $('#searchTerm').val();
                self.doSearch(searchTerm);
           });
      };  


It turns out it was a mistake I made by not returning a value from the annoymous function, so it would stop flow of execution.



      self.init = function() { 
           $('.search-btn').on('click', function() {
                var searchTerm = $('#searchTerm').val();
                self.doSearch(searchTerm);
                return false;
           });
      };  


Monday 25 June 2012

oauth twitter plugin grails problem with production

My production app is deployed via cloudfoundry, so I get a url like myapp.cloudfoundry.com. However, I wanted my main domain, myapp.com to forward to that domain. Everything worked initially until the point where it forwards the user to sign in with twitter. All I got was a blank page. Turned out that I need to set the production environment variables in Datasource.groovy like so:

production {
  ...
grails.serverURL = "http://www.myapp.com/" //needed b/c of spring security and url createlinks
grails.app.context = "/"
  ...
}

get app context in grails view

I have a custom link that I need to render so the search engines can index the search terms more effectively. Specifically, I wanted to generate something like this:

http://mytestdomain.local:8080/tweetcommendation/review/business-name/1_Informotion%20Software_Vancouver,%20BC

However, I found that I couldn't do this using createLink, because it only had the concept of controller / action mapping, and my /review/business-name/${businessName} is not mapped to a controller (it's just defined in DataSource.groovy).

Originally, I had something like this:
${request.contextPath}/review/business-name/${it.id}_${it.name}_${it.location}

That way works. However, I actually found a cleaner solution that I thought I'd share:

${resource(file: "review/business-name/${it.id}_${it.name}_${it.location}")}

Sunday 24 June 2012

Grails app on cloudfondry: Caused by: java.lang.OutOfMemoryError: PermGen space

So I was deploying my app to production (yay) on cloud foundry today. The deployment was successful, but then the system would crap out whenever I goto any of the pages:

504 Gateway Time-out nginx

I checked the logs:

vmc log

...and it appeared to be a permgen issue:

Caused by: java.lang.OutOfMemoryError: PermGen space



To solve it, type this in:

vmc env-add tweetcommendation "JAVA_OPTS=-XX:MaxPermSize=512m"

 To check that you have correctly set the value:

me@tommy:~/repo/tweetcommendation/target$ vmc env tweetcommendation

+-----------+----------------------+
| Variable  | Value                |
+-----------+----------------------+
| JAVA_OPTS | -XX:MaxPermSize=512m |
+-----------+----------------------+

Friday 22 June 2012

Grails - Twitter Bootstrap with the resources plugin stops working

I was mucking around last night with the intention of making my resources load more efficiently, and all of a sudden my Twitter Bootstrap enabled  drop downs are no longer working. This was what I had in my declaration initially (after I was mucking around):



 modules = { 

      core { 

           dependsOn 'jquery, jquery-ui, jquery-theme, bootstrap, utils'  

           resource url: '/js/spin.js', disposition: 'head' 

           resource url: '/js/jquery.spin.js', disposition: 'head' 

           resource url: '/js/bootstrap.min.js', disposition: 'head' 

      } 

}


It turned out that was a really bad mistake, as the bootstrap module already declares a bootstrap.js. By re declaring the dependency elsewhere, you get into weirdness with some of the bootstrap plugins not working the way it should, in my case the dropdowns.




Tuesday 19 June 2012

Shorten urls using the bit.ly api without using oauth

There is a poorly documented feature of bit.ly, and that is using their shortening url without using oauth, as long as you're fine with stats being posted to your account (which is what you want in most cases when shortening urls anyways).

In their api for shorten (located @ http://dev.bitly.com/links.html#v3_shorten), it appears that it only accepts an oauth access_token.

However, there is a small blurb on another page allow the user to use the parameters apiKey and login. Just goto http://bitly.com/a/your_api_key and you will see your login and apiKey information. Use these two parameters instead of the access_token, and then you'll be in business.

So an example would look like this:


/v3/shorten?apiKey=blah&login=blah&longUrl=http%3A%2F%2Fgoogle.com%2F

Hope that saves someone the ten minutes I took to figure it out!


Saturday 16 June 2012

Fixing grails problem: java.lang.IllegalStateException: Method on class [] was used outside of a Grails application. If running in the context of a test using the mocking API or bootstrap Grails correctly.


So I was getting this exception when I am writing a unit test for a controller for an application that uses the grails mongo gorm plugin:

 java.lang.IllegalStateException: Method on class [com.tweetcommendation.Tweetcommendation] was used outside of a Grails application. If running in the context of a test using the mocking API or bootstrap Grails correctly.  

I'm also writing the unit using the annotation style (ala 2.0+ style). It turns out that this problem comes up when you don't define the @Mock annotation with the domain class (which happens to be mapped with mongo).
So add in the domain class with the @Mock annotation:


 @Mock([DomainClassMappedWithMongo])  


Grails exception when rendering a view: java.util.EmptyStackException

So I was getting this exception after a change in my view page:

 Stacktrace follows: 

 java.lang.RuntimeException: Error initializing GroovyPageView 

      at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) 

      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) 

      at java.lang.Thread.run(Thread.java:662) 

 Caused by: java.util.EmptyStackException 

      at java.util.Stack.peek(Stack.java:85) 

      ... 3 more  

This is what I added:

                               <div id="positive-review"> 

                                    <img 

                                         src="${resource(dir: 'images', file: 'Thumbs_up_icon_sm.jpg')}" 

                                         width="38px" height="38px"></img> <span>${reviewCountsMap['1']}</span> 

                               </div> 

                               <div id="neutral-review"> 

                                    <img src="${resource(dir: 'images', file: 'Icon_neutral.png')}" 

                                         width="38px" height="38px"></img> <span>${reviewCountsMap['0']]}</span> 

                               </div> 

                               <div id="negative-review"> 

                                    <img 

                                         src="${resource(dir: 'images', file: 'thumbs-down-icon.jpg')}" 

                                         width="38px" height="38px"></img> <span>${reviewCountsMap['-1']}</span> 

                               </div>  

Notice the error? It's an extra square bracket after reviewCountsMap['0]! Remove it and you'll be fine.

Thursday 14 June 2012

No signature of method: org.codehaus.groovy.grails.web.servlet.GrailsFlashScope.success() is applicable for argument types: (java.lang.String) values: [Comment created!]

So I'm trying to add informational flash messages to display to my users. In my controller I set something up like this:



                if (createAndSaveComment(tweet, comment, currentUser) != null) { 

                     rabbitSend('comment.created', '', tweet.id) 

                     flash.success('Comment created!') 

                }  


Seemed correct, right? WRONG! This is what the error I got:



 No signature of method: org.codehaus.groovy.grails.web.servlet.GrailsFlashScope.success() is applicable for argument types: (java.lang.String) values: [Comment created!]  


Turns out I'm doing it wrong. It should look like this:



                if (createAndSaveComment(tweet, comment, currentUser) != null) { 

                     rabbitSend('comment.created', '', tweet.id) 

                     flash.success = 'Comment created!'

                }  


You might be snickering at this point because I made such a stupid mistake...well it's late in the day and I've been coding since 8am okay? Give me a break!


Tuesday 12 June 2012

Parameter values not showing up in message.properties for a Grails/Spring app

So I was troubleshooting why my parameters were not showing up even though i have debugged through the app and I know it is passing it to my messages.properties.

This was originally in my messages.properties

tweetcommendation.negative.3=Wow probably the best experience I've ever had. @{0} shame on you. #tweetcommendation

At first glance, it doesn't seem like a problem, and there are no error messages in the console. I'll give you another 10 seconds. See the problem? It turns out that I have a single quote that needs to be escaped in order for the property {0} to render
The correct message:

tweetcommendation.negative.3=Wow probably the best experience I''ve ever had. @{0} shame on you. #tweetcommendation

Monday 11 June 2012

How to make your params show up in the Spring security default LoginController's login/auth page

In my app, I have a user submit a form with a text field first. At the point, if they're not registered yet, Spring will render the login/auth page. The problem is, I wanted that input to show up on the login/auth page, and by default that param doesn't show up (because the Spring Security plugin renders the login/auth page).

So what do you do? Would you have to dig deep into the Grails/Spring Security code? You probably could but you could actually be wasting time! If one looks at the docs for the Grails Spring Security Core documentation, you could see that there is a param you can set:


PropertyDefault ValueMeaning
apf.filterProcessesUrl'/j_spring_security_check'Login form post URL, intercepted by Spring Security filter.
apf.usernameParameter'j_username'Login form username parameter.
apf.passwordParameter'j_password'Login form password parameter.
apf.allowSessionCreationtrueWhether to allow authentication to create an HTTP session.
apf.postOnlytrueWhether to allow only POST login requests.
failureHandler. defaultFailureUrl'/login/authfail?login_error=1'Redirect URL for failed logins.
failureHandler. ajaxAuthFailUrl'/login/authfail?ajax=true'Redirect URL for failed Ajax logins.
failureHandler. exceptionMappingsnoneMap of exception class name (subclass of AuthenticationException) to which the URL will redirect for that exception type after authentication failure.
failureHandler. useForwardfalseWhether to render the error page (true) or redirect (false).
successHandler. defaultTargetUrl'/'Default post-login URL if there is no saved request that triggered the login.
successHandler. alwaysUseDefaultfalseIf true, always redirects to the value of successHandler. defaultTargetUrl after successful authentication; otherwise redirects to to originally-requested page.
successHandler. targetUrlParameter'spring-security-redirect'Name of optional login form parameter that specifies destination after successful login.
successHandler. useRefererfalseWhether to use the HTTP Referer header to determine post-login destination.
successHandler. ajaxSuccessUrl'/login/ajaxSuccess'URL for redirect after successful Ajax login.
auth.loginFormUrl'/login/auth'URL of login page.
auth.forceHttpsfalseIf true, redirects login page requests to HTTPS.
auth.ajaxLoginFormUrl'/login/authAjax'URL of Ajax login page.
auth.useForwardfalseWhether to render the login page (true) or redirect (false).
logout.afterLogoutUrl'/'URL for redirect after logout.
logout.filterProcessesUrl'/j_spring_security_logout'Logout URL, intercepted by Spring Security filter.
logout.handlerNames['rememberMeServices', 'securityContextLogoutHandler']Logout handler bean names. See Logout Handlers
adh.errorPage'/login/denied'Location of the 403 error page.
adh.ajaxErrorPage'/login/ajaxDenied'Location of the 403 error page for Ajax requests.
ajaxHeader'X-Requested-With'Header name sent by Ajax library, used to detect Ajax.
redirectStrategy. contextRelativefalseIf true, the redirect URL will be the value after the request context path. This results in the loss of protocol information (HTTP or HTTPS), so causes problems if a redirect is being performed to change from HTTP to HTTPS or vice versa.
switchUser URLs See Switch User, under Customizing URLs.


Notice the auth.useForward flag.
All you need to do is to set this in your Config.groovy:

grails.plugins.springsecurity.auth.useForward = true
..and you will see your param(s) in the login/auth page, since it's a redirect and not a full render.

Sunday 10 June 2012

If you're experiencing javascript weirdness with load ajax page in a Grails application ...

If something you expect isn't working the way it should for a page that is loaded via ajax (ie. using jQuery's $.load() method), here are a couple common culprits that I'd thought I share before blaming the javascript libraries.

In anyone is interested, in my case it was jQuery dialog refusing to close after a $.dialog('close').

Here are the frameworks/plugins I was using when I experience this problem:

Grails
Resources plugin for Grails
Sitemesh for rendering.

I'm using Grails to load up the views as well as any ajax page loads.

Tip #1 - When using the resources plugin, check to see if you want to set disposition="head". For knockout, they suggest putting it in the head to ensure it loads first. By default if you don't put disposition="head" it will defer the rendering after the body.

Tip#2 - Check any view loads via ajax uses a different "main" layout template. Most likely, your default "main" layout includes the js resources. If you're doing an ajax load such as jQuery's $.load(), then if make sure you don't reload the js libraries again. Create a custom layout or don't use a layout to load the view. (ie. <g:render template...> instead).

Tip#3 - Again when rendering an ajax page and using a declared resources plugin module, make sure that module doesn't inherit (using the keyword "depend") to bundle the javascript, because again, the core js bundles have already been loaded.



     //bad example 

      "myajax" { 

           dependsOn 'core' 

           resource url: '/js/index/index.js', disposition: 'head' 

      } 

     //good example 

      "myajax" { 

           resource url: '/js/index/index.js', disposition: 'head' 

      } 


Knockout js: Uncaught Error: Unable to parse bindings. Message: ReferenceError: blah is not defined; Bindings value: click: blah, attr: {twitter_id: id}


I'm still learning knockout js, and so far I must say it's nice to have the framework worry about the DOM for you while you worry only about the view model. I ran into an issue just now with knockout complaining about something like this:


Uncaught Error: Unable to parse bindings.
Message: ReferenceError: blah is not defined; 
Bindings value: click: blah, attr: {twitter_id: id}


Here is my original code:


           <ol data-bind="foreach: {data: results}"> 
                <li>
                     <div class="well">
                          <div class="stream-item-header">
                               <img data-bind="attr: {src: profileImageUrl}"> <strong
                                    data-bind="text: name"></strong><span></span> <span
                                    data-bind="text: screenName"></span>
                          </div>
                          <div>
                               <span class="search-description" data-bind="text: description"></span>
                               <span data-bind="text: location"></span>
                               <p data-bind="text: url"></p>
                               <button data-bind="click: $parent.blah, attr: {twitter_id: id}"
                                    class="btn btn-large btn-primary select-business" type="submit">Select
                                    Business</button>
                          </div>
                     </div>
                </li>
           </ol>  

In my js code:


 function SearchViewModel() { 
      var self = this;
      self.results = ko.observableArray();
      self.blah = function() {
           alert('hello');
      };
 }  

Okay so what is going on I was wondering? Why doesn't this work? After a minute, then I realized that of course it won't work. When it is rendering the button, it is rendering a row at a time. And since I defined the method on the view model, that row does not have access to my blah function, so it complained.

To solve the problem, I changed to the following in the view code:


           <ol data-bind="foreach: {data: results}"> 
                <li>
                     <div class="well">
                          <div class="stream-item-header">
                               <img data-bind="attr: {src: profileImageUrl}"> <strong
                                    data-bind="text: name"></strong><span></span> <span
                                    data-bind="text: screenName"></span>
                          </div>
                          <div>
                               <span class="search-description" data-bind="text: description"></span>
                               <span data-bind="text: location"></span>
                               <p data-bind="text: url"></p>
                               <button data-bind="click: $parent.blah, attr: {twitter_id: id}"
                                    class="btn btn-large btn-primary select-business" type="submit">Select
                                    Business</button>
                          </div>
                     </div>
                </li>
           </ol>  

Knockout provides a way for a row to reference its root path but prefixing the '$' symbol (don't confuse this for jQuery, we're still in the view code!).


Saturday 9 June 2012

Stupid JS mistake on my part

I've started using knockout js for my declarative bindings and thought I'd a newbie javascript mistake on my part. I spend half an hour or so trying to figure out why my code that is loaded using jquery's .load() method is not working. According to the jQuery docs, the .load() method also loads any javascript sources as well. However, I found out (the hard way), that if there's a silly mistake like the following in the script that gets parsed, jQuery won't load the javascript, and will not report any errors.

The following code is what I had:


 function Page(viewModel) { 
   /** --- VARIABLES --- */
   var self = this;
   var self.viewModel = viewModel;
   /** --- METHODS --- */
   self.init = function() {
     $('.search-btn').on('click', function() {
       alert('hello');
     });
   };
   self.updateSearch = function() {
     viewModel.results.push('s');
   };
 }  

Can you spot the mistake?

It's here:


 var self.viewModel = viewModel;  

To fix it, make it so:


 var viewModel = viewModel;  



Thursday 7 June 2012

Bootstrap view issue - span class goes on bottom in a row div


So I wrestled with the Bootstrap a bit just now, trying to get the layout to work.

The problem: I have a row class that I nest a span9 and a span3 class in. Seems pretty standard since it should add up to 12. Here is my original code:


      <div class="row"> 

           <div class="span9 well"> 

                <form class="form-horizontal"> 

                     <fieldset> 

                          <legend>We love to hear from you!</legend> 

                          <div class="control-group"> 

                               <label class="control-label" for="selectError">Question 

                                    category</label> 

                               <div class="controls"> 

                                    <select id="selectError" class="input-xlarge span3"> 

                                         <option>I have a technical issue</option> 

                                         <option>I have a comment</option> 

                                    </select> 

                               </div> 

                          </div> 

                          <div class="control-group"> 

                               <label class="control-label" for="textarea">Textarea</label> 

                               <div class="controls"> 

                                    <textarea class="input-xlarge" id="textarea"></textarea> 

                               </div> 

                          </div> 

                     </fieldset> 

                </form> 

           </div> 

           <div class="span3 well">hello</div> 

      </div>  


Look at what happened:


Okay so try to spot the error (if you can). Give up?

The problem is the "well" class affecting the div. One of the features of Bootstrap was that users can combine classes together, but in case it doesn't do quite what we wanted. So if you want the "well" class, you would have to wrap it in another div, like so:



      <div class="row">  
           <div class="span9">  
                <div class="well">  
                     <form class="form-horizontal">  
                          <fieldset>  
                               <legend>We love to hear from you!</legend>  
                               <div class="control-group">  
                                    <label class="control-label" for="selectError">Question  
                                         category</label>  
                                    <div class="controls">  
                                         <select id="selectError" class="input-xlarge span3">  
                                              <option>I have a technical issue</option>  
                                              <option>I have a comment</option>  
                                         </select>  
                                    </div>  
                               </div>  
                               <div class="control-group">  
                                    <label class="control-label" for="textarea">Textarea</label>  
                                    <div class="controls">  
                                         <textarea class="input-xlarge" id="textarea"></textarea>  
                                    </div>  
                               </div>  
                          </fieldset>  
                     </form>  
                </div>  
           </div>  
           <div class="span3">  
                <div class="well">hello</div>  
           </div>  
      </div>  




Hope that helps somebody who isn't a Bootstrap guru like myself!


Sunday 3 June 2012

Problems deploying a node js app to cloudfoundry

 I have a small Node.js app that exposes an JSON service which I wan to use in my main app. However, I ran into a hitch with deploying to CloudFoundry. When I do a deploy, this is what I get:




 Error: EACCES, Permission denied  



Turns out the culprit was this in my init method:



 var port = 8081;



I actually needed to do this instead:



 var port = process.env.VCAP_APP_PORT || 8081;



Hope that helps somebody!



intellij Failed to run grails command: JDK is not defined

I'm starting to experiment with IntelliJ because I have a javascript portion of code in my Grails app, but one of the first things I'm running into when using Grails for IntelliJ is this:

Failed to run grails command: JDK is not defined

The solution is to define your JDK by going to File -> Project Structure, and then putting a value in the JDK.

Coming from an Eclipse background I'm sure I'll encounter more silly problems like these...but hey the JS support for IntelliJ is supposed to be the best, so I'll give it a try.