Expand my Community achievements bar.

Enhance your AEM Assets & Boost Your Development: [AEM Gems | June 19, 2024] Improving the Developer Experience with New APIs and Events

Detecting changes made inside a fill method

Avatar

Level 2
Hello, i am having troubles when using DataServices in my
app. Here's

the thing:



I have an Assembler and a DataService component that points
to that Assembler. I have a Datagrid for showing a list of elements
and a Form for inserting new one. The DataGrid is filled by
pressing a button that calls the fill method of the Assembler.



The type of object i am using has a property called winner
that is a boolean and defaults to false, the fill method obtains a
list of bids from the database and before the return statement, it
iterates it to determine if each bid is a possible winner or not,
setting the winner property to true or false. So each time the fill
method is executed by the client or by a refreshFill it checks
these conditions and determines possible winners.



I call the fill method and the DG is filled with the result
of the fill method, then i create a new Bid and fill it with the
Form (the

default value for winner is false) and then call the
createItem method, which inserts it into the database and
automatically triggers an refreshFill that once again obtains the
list of bids and determines which one is a possible winner and
which isn't.



The problem is that if the recently added item is a possible
winner i am setting its property to true but on Flex it remains as
false. Additionally if any other bid that was already on the list
changes its property from true to false or viceversa, Flex won't
see these changes.

Before the return statement of the fill method i am printing
the values of the bids and there i see that the values of the
winner property are in fact being done but on the DataGrid those
changes don't occur :S.



So the thing is that the refreshFill that is automatically
triggered after the createItem is obtaining the right data but Flex
just doesn't show it correctly.



Any ideas? Please help!!!
9 Replies

Avatar

Level 3
Hi



Did you check the DataServiceTransaction API. I think you
should push the new winner by using the update method



William Chan

Avatar

Level 2
Thanks for replying, i have been trying to solve this for a
week now. I found that changes made to items on the collection are
not detected, only added or removed items, and as you mentioned,
according to documentation, you should do an update but my question
is how to do this? i mean where should i call the update, do you
have an example? I have been trying this but no success :(



If you have an example PLEASE PLEASE help me out

Avatar

Level 3
Hi



Suggest to have a previousWinner stored in your assembler,
when there is an update, delete or create. Run your logic to
determine who is the winner.



public void pushNewWinner()

{

Member previousWinner = winner;

winner = findWinner();

if (winner.id == previousWinner.id)

return;

DataServiceTransaction dst =
DataServiceTransaction.begin(useJTA);

String[] changedProperties = {"isWinner"};

Member original = winner.clone();

original.isWinner = false;

winner.isWinner = true;

dst.updateItem("Members", winner , original
,changedProperties);

orignal = previousWinner.clone();

previousWinner.isWinner = false;

previousWinner.isWinner = true;

dst.updateItem("Members", prevopisWinner , original
,changedProperties);

dst.commit();



}



You might need to try catch updates and dst.commit()
infinally, catch exception to dst.setRollbackOnly();





William Chan

Avatar

Level 2
Thanks a lot for replying, your example is being of help but
i think you misunderstood my post and i still have some doubts.



More than one item can be a winner, not just one, so i will
have to call an update for each item.



On my fill method i have something like this:



public List fill(List fillParameters){

List results = new ArrayList();

results = dao.getBids();

results = checkWinners(results); //this function checks each
item and sets the winner porperty to true or false.

return results;

}



So when i call on Flex DataService.fill() it obtains the list
of bids and each has its winner property to true or false. Then i
insert a new item and the fill method is executed again (due to
autoRefreshFill) and winner properties is set again but the
updateCollection message only includes the new added item, it
doesn't check for updates.



So now, the real deal is where would i call the updateItem to
push the changes? Should i call the updateItem inside the
createItem function? on the refreshFill function? inside the fill
function?



I have checkWinners() function which is the one i call inside
the fill function and that sets the winner property of each item,
should i call the DataServiceTransaction.updateItem from there? I
have my doubts because i am calling this function inside the fill
method.



So it all sums up in "where should i call the updateItem?"



Thanks for you help, hope you can help me out with this last
issue :)

Avatar

Level 3
Hi,



I made a mistake in previous message. It should use the
current transaction inside the create, since there is already a
datatransaction.

DataServiceTransaction dt =
DataServiceTransaction.getCurrentDataServiceTransaction();

You don't need to call commit in this case. I suggest to put
the updates in the create when you don't want any update messages
from regular fill.

Another solution create a message destination in the app, and
use message handler to force other clients to refill



William Chan



William Chan

Avatar

Level 2
I thought about putting the updateItem inside the createItem
but the thing is how to access the managed list from there? i mean,
is it possible to access a managed list from other place that is
not the fill method?

Avatar

Level 3
Hi,



I think you can use
org.apache.commons.collections.CollectionUtils. When you run your
fill method, put all winners to a collection. At the end of the
fill method compare lastWinnders collection by
CollectionUtils.subtract(winners, lastWinner) if lastWinners
collection is not null. You can get new winners. Then you use
DataServiceTransaction to push the update by changing winner from
false to true. Vice versa, CollectionUtils.subtract( lastWinner,
winner) from true to false. After the updates pushed, assign
lastWinners = winners. In this case, there is no updates push to
clients if winners == lastWinners



William Chan

Avatar

Level 3
Hi



Did you get it working? I found there is an issue where the
submitted client didn't get update message. I think the workaround
is the submitter refill after the result event. Would like to hear
from you. Please free feel to email me if there is anything which I
can help.



wichan@adobe.com

William Chan

Avatar

Level 2
Couldn't actually make it using the transaction.updateItem( )
method, so what i did was to refill on the submitter on the result
event and then refill on the other clients on the message event.
That seemed to work but i still wonder what could be the correct
approach.



I did a sample using the Flex CRM Sample application, i can
email it to you so you can check out for yourself what the real
deal is, please let me know.



Diego