Expand my Community achievements bar.

Dive into Adobe Summit 2024! Explore curated list of AEM sessions & labs, register, connect with experts, ask questions, engage, and share insights. Don't miss the excitement.

event.token.kind is undefined

Avatar

Level 3
Page 1225 of the developers guide mentions that you can check
the event.token.kind of a ResultEvent to determine what action was
completed. However no matter what I do I am getting back an
undefined value. Fill, Update/Save, Delete all work according to
the database.



example in the book

private function resultHandler(event:ResultEvent):void {

Hourglass.remove();

if (
event.token.kind == "create") {

dg.selectedIndex = contacts.length - 1;

}

else if (event.token.kind == "delete" &&
contacts.length>0) {

var index:int = event.token.index

< contacts.length ? event.token.index : contacts.length
-1;

dg.selectedIndex = index;

contact = contacts[index];

}

else if (event.token.kind == "fill" &&
contacts.length>0) {

dg.selectedIndex = 0;

contact = contacts[0];

}



I have tried the following



DataMessage.getOperationAsString(DataMessage(event.token.message).operation)



and it sort of works, but it gives me two messages on the
return of a delete statement transactioned and delete.



Any ideas?
8 Replies

Avatar

Level 3
Hi Ken,



The transactioned result corresponds to the commit and the
delete corresponds to the delete. DataService operations are sent
within a batched or transactioned message and this will be the last
result dispatched so if you want to use a general result handler
you should base your post-completion processing on that.



As for token.kind, that looks like a doc bug. The collection
events use a 'kind' property, but the DataService events don't. You
can inspect the token message operation on generic result events as
you're doing or you may want to just add a responder (that wraps
result and fault handler functions) to the token returned when you
invoke dataService.commit().



Thanks,

Seth

Avatar

Level 3
Thanks Seth -



Right the documentation is wrong. But that is not the
problem, it is a user experience issue. I want to know when
something is saved or deleted or loaded (fill), meaning when the
processing is done. I get an event back, but what it tells me is
less useful now than it what the documentation eluded to - which is
more of what I am looking for.

Avatar

Level 3
Hi Ken,



When you invoke fill() the asynchronous result or fault is
dispatched and you can check the event.token.message.operation to
see if it's in response to your fill or not. Like commit(), fill()
returns an AsyncToken that you can add a result/fault responder to.
AsyncToken is a dynamic class so you can also add whatever else you
want to it. For example:



var token:AsyncToken = ds.fill(...);

token.kind = "fill";



and then in your result handler you could look for your
dynamic prop:



if (token.kind != null && token.kind == "fill") ...



The createItem() and deleteItem() methods work this way as
well. Updates are the one operation that doesn't generate an
AsyncToken because they are tracked implicitely and either
auto-commited or commited as a batch when you call commit(). In the
auto-commit case a result/fault event is dispatched upon completion
and you can inspect event.token.message.operation to watch for them
- no batched/transactioned event is dispatched because you didn't
explicitely call commit(). When you're not using auto-commit,
you'll get the same general events for updates/etc. but you'll also
get the event for the commit itself.



Best,

Seth

Avatar

Level 3
Seth -



I got all that. The problem is on the delete you actually get
2 messages. One for the delete and one for the commit (save). This
is because the item is deleted, great, and then the commit happens.
So for a logical unit of work you have problems with giving the
user a message like "Your delete worked" because you then get
"...and oh yea your save that you did not issue worked as well".



And one other thing the token.kind is actually undefined. At
least that is what I am getting back.



Ken

Avatar

Level 3
Hi Ken,



token.kind is undefined by default. However, token is an
instance of AsyncToken, a dynamic class, so if you want to add a
"kind" field to your tokens you can do that. The token (plus any
additions you make to it) is handed back on the result or fault
event so you can drive your completion processing that way. Sorry
for any confusion there.



If you're in auto-commit mode you should only get one event
for the deletion. If you're seeing two events in that case it's a
bug. If you invoke commit() you should get one for the deletion and
one for the commit. I'd recommend waiting for the result event for
the commit to inform the user that the delete worked.



Best,

Seth



Avatar

Level 3
Seth -



That makes a liitle more sense. But how would one go about
doing what you are talking about? Do you simply create a new
AsyncToken("fill") then call ds.fill() and hope for the best? Or do
you have to attach the token to the data service? Or do you set a
configuration parameter? Or ???



The current documentation page 1225 of the Developer's Guide
makes no mention of that, it appears that it just happens
magically.



Thanks again.



Ken

Avatar

Level 3
The documentation on page 1225 of the dev guide is wrong.
I've passed along a request to have it corrected.



If you look at the DataService API, you'll note that several
methods (fill(), commit(), etc.) return an AsyncToken. This token
is a dynamic class, meaning you can assign ad-hoc data to it, and
the token instance will be returned along with the async result or
fault event for the async call. It is the "T" in the Asynchronous
Completion Token design pattern - used by DataService,
RemoteObject, etc.



When you invoke fill() it returns an AsyncToken to you. You
can add data/context to it like so:



private function doFirstStep():void {

var token:AsyncToken = ds.fill(... your fill args...);

// Add some custom info to the token

token.x = 10;

token.foo = "bar";

token.step = "1st fill";

}



Later, when the result event for this fill is dispatched it
will have this same token attatched to it and you can access the
data you've added to the token to drive your result processing:



private function resultHandler(event:ResultEvent):void {

if (event.token.x == 10) {

// Do something

}

trace(event.token.foo);

if (event.token.step = "1st fill") {

// Do your next step

}

}



Hope that helps,

Seth

Avatar

Level 3
Seth -



Actually I had not noticed. Thanks!



Ken