Just a quick note to detail some interesting issues I ran into last night. I was writing a very simple report tool for a client. He has a process that runs a large set of MLS queries and does a lot of - well - stuff. It is a slow process so I've set it up so that it runs one day at a time based on a simple URL parameter. While this works well enough he asked if I could build a simple front end to it so he could select two dates and have it process each day one by one. Simple, right?
So, in my last post on this topic, I mentioned that I was surprised at how many times this "simple" topic kept coming up on my blog. In a way, this has turned into the series that just won't die - no matter how many times I think I've covered every little detail.
I discovered something new last night, which was painful like all good learning tends to be. I'm building a Cordova application for a client that - like most hybrid apps - can be run via a local web server for most of the development process. This particular project involves a complex dynamic form process that isn't Cordova-related at all. Later on we'll be adding in barcode scanning but for the foreseeable future I'm running it as a simple web page.
My application makes multiple XHR requests to the client's server for various things, and in order to make that work I'm using CORS. I won't need CORS once I switch to a proper hybrid app. I could also use Ripple too. But again - I just don't need this now at this point in the development.
Everything was kosher until I began to lock down some of the calls to require a session variable. In all my Cordova apps before I relied on the fact that sessions (cookie-based sessions) "just work" when doing XHR. If your back end server responds with cookies, then your front end code will respect that and send them back on future requests. This enables session management to work on your server.
Except when I used CORS! I couldn't understand why I kept getting an error saying that an earlier session variable wasn't defined. Like any good developer, I opened up my dev tools and examined the cookies being sent back and forth in my calls. (And again, if you have no idea how that is done, speak up in the comments.) I noticed right away that the session cookies were not sticking. So what was the problem?
If you read the docs for XHR and CORS you discover this little gem:
The most interesting capability exposed by both XMLHttpRequest and Access Control is the ability to make "credentialed" requests that are cognizant of HTTP Cookies and HTTP Authentication information. By default, in cross-site XMLHttpRequest invocations, browsers will not send credentials. A specific flag has to be set on the XMLHttpRequest object when it is invoked.
In English, the cookies won't go back and forth. Raise your hand if you knew that. Now lower it you liar. ;) Luckily it is easy enough to fix with a flag in the XHR object. AngularJS exposes it as a property, withCredentials.
But you then may run into yet another issue. My CORS header on the server was using Access-Control-Allow-Origin with a value of *. Basically, anyone and everyone can hit me. When you enable credentials on XHR, this is no longer allowed. Basically the browser is saying, "Sorry, this server is just too promiscuous for me." So for now, I've simply specified my local dev server in the origin. Once I get further down the line I'll probably remove CORS completely as it won't be needed for Cordova.
So I know (think?) there is a significant portion of my audience who do not use Twitter, and for those of you who have avoided that trap (don't let anyone fool you, it is a trap), you may have missed me recently raving about the Ionic Framework. Briefly, Ionic is a way to work with Cordova/PhoneGap apps using Angular directives. It has an incredible collection of UI and UX controls that can be helpful to you. I'm still new to Angular and I've found their controls easy to use. I plan on blogging about this a bit more later, but I wanted to tell you about something else these folks created - ngCordova.
A reader asked me a simple Ajax-y type question this morning and I thought I'd turn it into a simple blog post. We've all done, or at least seen, related selects before. That widget where you select something in one drop down and it drives the data in the second drop down. What he was asking is how you would support being able to select multiple items in the first drop down. Here is an example of that. Before I go on, let me say that while the back end of this is built in ColdFusion, it absolutely does not matter what back end you use. Oh, and please do not ask me to build you a PHP version! ;)
Over the holiday weekend Cordova 3.5.0 was released. You can read details about the update here: Apache Cordova 3.5.0. Another update was to the documentation, which now includes a What's Next guide that talks about what Cordova developers should learn, think about, and bookmark for future reference after they've learned the basics. I think this is an important piece of documentation and I'm happy to see it finally published. (Oh, and I may be a bit biased as I wrote the first draft. ;)
Also released is a new Security Guide for Cordova developers. Definitely check this out as well.
That's probably the longest title I ever used for a blog post. A PhoneGap user came to me recently with an interesting problem. His application was set to be portrait only. In case you weren't aware, you can lock orientation for an application using this config.xml value:
Just a quick note that NetTuts has published an article I wrote on working with the Intl class. Enjoy. Working with Intl. Please leave comments about the article there. Please post pictures of kittens in the comments below.
Before I begin, I want to point out that the title of this blog is far more complex-sounding than what I'm actually going to demonstrate here. GMail has an interesting way to handle large mail threads. When you view it, only the most recent few emails will be visible. The rest will be collapsed and are loaded as you click them.