The problem with this approach is that it will eventually come back to bite us; we will forget about the global variable, someone else won’t be aware of it and, consequently, they will create some other way to get the same information. Worst of all – it won’t always work.
Three notes we need to write on bright yellow stickies and attach to our monitor:
- We are going to write modular code (from now on, at least)
- Event-based programming is a good thing
- Global variables should be used only as a last resort
Get The Location
So, first, what is the problem? Getting the user’s current location!
This will happen asynchronously, and the UI element we need to update is in another file. Of course, this is modular code!
We know that the API call Titanium.Geolocation.getCurrentPosition uses a callback to let us know when it has found a location.
Put it somewhere useful
Now we could create a global variable outside of the callback and use that to get the information.
but that only helps if the UI element we need to update is in the same JS file as the callback. That’s not possible when writing modular code. Also, we definitely should not have UI code mixed in with the geolocation logic.
Put it somewhere better using an event listener
So what are we going to do? The first thing is to get rid of the global variable and fire an event to indicate that a location has been successfully received.
So now, anywhere in the application when we need to get the location information, we can create a listener to get the coordinates delivered in the event payload. This is nice; no globals necessary at all!
But there is another way; use a callback within the callback
Let’s pass in a function to call when the device has finished getting the location. Along with firing the event, we will call the function passed in as a parameter with the coordinates we received from the device.
Somewhere else in our code we need to get the location and update the UI element with the information.
Modules are GOOD! That’s what Kevin said!
OK, now we have the GPS code in an include file, separated from the UI, and we can make calls from anywhere and get the location information from either an event or a callback. BUT we are not quite yet there – what about modules and CommonJS and all that “requires” stuff?
We want to be good Appcelerator citizens, producing code that is more code-strong than kitchen-sink! After all, the KitchenSink only exists to demonstrate API functionality, and not to act as a best-practice example.
Let’s convert our location file into a module; just add “exports” before the function name to make it public.
In our ui.js file, where we created the window, we need to load the module containing the currentLocation function. In the complete example, we have named the file “maps.js”, so we need to add the
Remember: don’t include the “.js” extension when using require; it’s not needed.
var maps = require('lib/maps');
Then when you call the method it looks like this:
// do the callback to get current location maps.currentLocation(gpsCallback);
Here is the complete ui.js file
Using callbacks and events are good for your code; it encourages decoupling and better separation of business logic from the presentation layer. From now on, we will be strongly encouraging a more modular approach to application development, and this will be reflected in all the content we will be bringing you in the near future.
Keep coding strong!