The next thing we need to do with our application is keep track of information across all players to determine global statistics. To do that, we will create an Event Handler that is triggered any time a new WouldYa is created. Upon that event, we want to update a counter for each celebrity, and also check to see if we have a new top rated celebrity and update a record for that position.
If you wish, you can download the complete Part III project file from Download Tutorial Part 3 Sample Files and then unzip and then either run newapp again from this directory to use this application or copy the files that are enclosed to the application directory you created in a previous section Installing FatFractal allowing the copy to replace all the previous files.
If you have not scaffolded your app already, it is not a problem, just run ffef newapp, using your subdomain, as before from the directory with the Part III files you have just downloaded and it will set up all the things that you need.
> $HOME/ff/ffnsbin/ffef newapp hoodyoodoo <your subdomain>
Note: The subdomain refers to the organization name you signed up with, e.g. acme in acme.fatfractal.com
Note: When you download the project, the client application is configured to use a API that is already deployed and populated with data. This means you can run the application on your simulator immediately. To use your API, you should edit the Hoodyoodoo.java file as before to point to the API that you have set up.
In Part III, we will do the following:
One of the most powerful capabilities of NoServer APIs is the ability to create event based actions. From the last Tutorial, selecting a Celebrity creates a WouldYa record on the API. In Part 3 of the Tutorial, we will define an event handler that is triggered by a WouldYa Create event and then update the Celebrity resource with two counters.
The Event Handler must be defined in your application.fddl file that is in the ff-config directory that was created for you during scaffolding. See FatFractal Definition Language for more information.
The download of the project for Tutorial Part 3 also includes the files that were generated for you by the scaffolding process so that you can see what the application.fddl looks like at the end of the Tutorial.
The FFDL looks like:
CREATE HANDLER WouldYaCreate_1 ON /WouldYa Create as javascript:var h = require ('scripts/WouldYaEventHandlers'); h.handleWouldYaCreate (FF_EVENT_DATA_JSON);
This entry tells the NoServer Framework to create an event on WouldYa Create, and execute the handleWouldYaCreate function that is in WouldYaEventHandlers.js file passing in the event data.
We will now create a event handler JavaScript file that defines an additional object model called TopCeleb, and also adds additional information (selectedCount and rejectedCount) to the Celebrity objects whenever a new WouldYa record is created. The NoServer Framework will automatically add the selectedCount and rejectedCount ivars to the Celebrity class and will also create the TopCeleb class for you as well.
Note: the additional fields: {number} selectedCount {number} rejectedCount
are added lazily to the returned data for the Celebrity class. You can modify the model class in your Objective C class if you like, or just access the data as returned as you wish.
To create this Event Handler, we create a javascript file (in this case called WouldYaEventHandlers.js) in the /ff-scripts directory of your application. The basic structure of the file is:
var ff = require('ffef/FatFractal');
function handleWouldYaCreate(json) {
… do some stuff
}
exports.handleWouldYaCreate = handleWouldYaCreate;
FatFractal.js is the server-side encapsulation of the NoServer API that is available to the EventHandler functions. For more information, see the HTML5/JS SDK Reference.
This gives us another example of the power of NoServer APIs. We are now going to create another RESOURCE called TopCelebrity which will be of TYPE Celebrity. This allows us to easily reuse our object models for other purposes. This new resource will keep track of the top rated celebrity over time.
Let’s have a look at what data we get from the event:
var data = ff.getEventHandlerData();
The data that was created by the CRUD Create event (a new WouldYa in this case) looks liks:
{
"guid":"2T0M7sJpXjaJp7OZtzQhK4",
"updatedAt":1330302739991,
"createdBy":"kevin",
"createdAt":1330302739991,
"rejectedGuid":"evusq-FzgU-ZgN0vR6pZv7",
"ffUrl":"/ff/resources/WouldYa/2T0M7sJpXjaJp7OZtzQhK4",
"selectedGuid":"xQ08Si91cPg3JEuDOR2wz4",
"clazz":"WouldYa",
"ffRL":"/WouldYa",
"updatedBy":"kevin",
"version":1
}
Get the Celebrity objects for the selectedGuid and rejectedGuid that are in the WouldYa from the DataStore.
var selectedCelebrity = ff.getObjFromUri("/Celebrity/" + data.selectedGuid);
var rejectedCelebrity = ff.getObjFromUri("/Celebrity/" + data.rejectedGuid);
Since we are adding selectedCount and rejectedCount fields to the Celebrity object lazily, make sure and set the initial values.
if(!selectedCelebrity.selectedCount) selectedCelebrity.selectedCount = 0;
selectedCelebrity.selectedCount++;
if(!rejectedCelebrity.rejectedCount) rejectedCelebrity.rejectedCount = 0;
rejectedCelebrity.rejectedCount++;
Next, we update the Celebrity resources with the updated counters.
ff.updateObj(selectedCelebrity);
ff.updateObj(rejectedCelebrity);
Now, we want to check if the results are that we have a new top rated celebrity.
First, get the latest top celebrity resource
var topCelebrityCheck = ff.getArrayFromUri("/TopCelebrity");
If there is no record, create the first one.
if(topCelebrityCheck.length == 0) {
var topCelebrity = ff.createObjAtUri(selectedCelebrity, "/TopCelebrity");
}
If there is a record, compare the two and decide whether to create a new one- or not.
var topCelebrity = topCelebrityCheck[0];
if(selectedCelebrity.selectedCount > topCelebrity.selectedCount) {
if (selectedCelebrity.guid == topCelebrity.guid) { // update the topCelebrity's counts
topCelebrity.rejectedCount = selectedCelebrity.rejectedCount || 0;
topCelebrity.selectedCount = selectedCelebrity.selectedCount;
ff.updateObj(topCelebrity);
} else { // it's a new one!
ff.deleteObj(topCelebrity);
ff.createObjAtUrl(selectedCelebrity, "/TopCelebrity");
}
} else if (rejectedCelebrity.guid == topCelebrity.guid) { // update the topCelebrity's rejected count
topCelebrity.rejectedCount = rejectedCelebrity.rejectedCount || 0;
topCelebrity.selectedCount = rejectedCelebrity.selectedCount;
ff.updateObj(topCelebrity);
}