where can i get the results of RequestContext's fire method?

108 views
Skip to first unread message

Elhanan

unread,
Nov 29, 2011, 10:31:03 AM11/29/11
to google-we...@googlegroups.com
the javadoc says that it sends the method invocations and setters to the server, now what?

the Editor Driver of Rf returns the requestContext, which doesn't give me a way to get the updated EnitityProxy i can send to the server, so i'm assuming it does get sent allready, but where can i get it from?

Jens

unread,
Nov 29, 2011, 11:05:18 AM11/29/11
to google-we...@googlegroups.com
You can listen for EntityProxyChange events on the EventBus. If your entity has been edited a corresponding event will be fired so you can fetch a fresh copy from the server.

Alternatively you could define a persist() method in your RequestContext that does return the persisted Entity. That way the persisted entity will be send back to you. Your code would look like:

ExampleRequest er = RF.exampleRequest();
er.persist(yourEntity).to(
  new Receiver<YourEntity>() { 
     public void onSuccess(YourEntity yourPersistedEntity) {
         .......
     }
  });

editorDriver.edit(yourEntity, er);
....
editorDriver.flush().fire(); //which will call the receiver from above.


-- J.

Thomas Broyer

unread,
Nov 29, 2011, 11:36:25 AM11/29/11
to google-we...@googlegroups.com
In addition to Jens answer: the RequestContext is a queue of invocations and edited proxies. Only when fire()d the RequestContext will flush that queue into an HTTP request.

Each invocation can have a Receiver set using Request#to(Receiver), and the RequestContext can have a global Receiver passed to the fire() method (note: its onFailure will only be called when the server cannot be reached or failed to decode the request or encode the response; independently of invocations: each invocation can fail independently of the others, and even if all of them fail, it doesn't make the global Receiver's onFailure to be called)

Elhanan Maayan

unread,
Nov 29, 2011, 12:06:28 PM11/29/11
to google-we...@googlegroups.com
but that's the thing i don't get, you refer to the point AFTER i persisted the entity, but what i'm talking about is how do i GET the new changed entity proxy so i could send it the persist method. i mean just using the fire won't magically persist the thing. unlike the find method in the entity locator, there's no persist method requestfactory can call (and i'm not defining any dao methods on the entity itself). . 

On Tue, Nov 29, 2011 at 6:36 PM, Thomas Broyer <t.br...@gmail.com> wrote:
In addition to Jens answer: the RequestContext is a queue of invocations and edited proxies. Only when fire()d the RequestContext will flush that queue into an HTTP request.

Each invocation can have a Receiver set using Request#to(Receiver), and the RequestContext can have a global Receiver passed to the fire() method (note: its onFailure will only be called when the server cannot be reached or failed to decode the request or encode the response; independently of invocations: each invocation can fail independently of the others, and even if all of them fail, it doesn't make the global Receiver's onFailure to be called)

--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To view this discussion on the web visit https://groups.google.com/d/msg/google-web-toolkit/-/wDLQdOYdWT0J.

To post to this group, send email to google-we...@googlegroups.com.
To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.

Thomas Broyer

unread,
Nov 29, 2011, 6:36:16 PM11/29/11
to google-we...@googlegroups.com
If you don't define a persist() or whatever method in your RequestContext (and call it), you won't persist or whatever anything. A fire() would send the changes to the server but it would then do nothing with them.

Elhanan

unread,
Nov 29, 2011, 10:50:01 PM11/29/11
to google-we...@googlegroups.com
ok i'm getting a sense of a chicken & egg, where i'm the chicken.. and the egg is the request context, let me try overview the way i see it:

define an interface extending request context, said interface will various dao like method , like Request<Proxy> getById(int) and Request<Void) persist (proxy)

get the requestContext from the request factory (let's call it ctx1)

call a getter method like getById (int) on ctx1) and fire it

on it's reciver call the driver's edit method sending a the proxy and another call requestContext (ctx2)

after editing call the driver flush method which will return ctx2

now ctx2 contains the changes made to the proxy

but if i call fire on ctx2, it would fire the changes to.. where , i mean i don't have a reference to changed proxy.

unless your saying that after the original call to getById i should also call persist  method, cause now i'm feeling like the egg here..

Thomas Broyer

unread,
Nov 30, 2011, 4:39:42 AM11/30/11
to google-we...@googlegroups.com
You can either keep a reference to ctx2 and call persist() after the flush() of the editor driver; or you can cast the RequestContext returned by flush() and call persist on it (the returned RequestContext is the one you passed as an argument to edit(), so it's == ctx2).

Or you can enqueue the persist() method on the ctx2 *before* calling edit(), so that you just have to fire() after the flush().

It goes like this:
  • ctx2.edit(myProxy) → now ctx2 tracks changes to myProxy (actually, it only created a mutable version of it –and only one RequestContext can have a mutable version of a proxy at a given time–, the changes are not "tracked", the RequestContext only does a diff between the mutable proxy and the immutable proxy at the time of the fire()). You can call edit() several times for the same proxy on the same RequestContext, it will always return the same mutable proxy (you can also call edit() with the mutable proxy, it'll be returned without error).
    RequestFactoryEditorDriver#edit automatically calls RequestContext#edit so you don't have to do it yourself if you don't need it.
  • ctx2.persist(myProxy).with(paths).to(someReceiver) → enqueues into ctx2 an invocation to the "persist" method with argument "myProxy" (can be a mutable proxy or immutable proxy, edit() will automatically be called at the time of the fire()) and paths "paths", when the context will be fired and the server responds, the Receiver will be called with the invocation result (the return value on the server, converted to a client type).
  • ctx2.fire() → gets the changes of the edit()ed proxies and serializes them (this is known as "operations"), gets the enqueued invocations and serializes them, sends the batch to the server. On the server, operations are processed (calls find() on your domain object –or the locator– and then calls the setters from the operations), then invocations (each invocation can fail independently of the others; after each successful invocation, the "paths" sent from the client for the invocation are resolved on the return value), and then return values and server failures are serialized to be sent back to the client (in addition, for each domain object seen as input or output, their "liveness" is checked and can result in a "PERSIST operation" or "DELETE operation" serialized for the entity, then the versions are compared to the one sent by the client and if they don't match an "UPDATE operation" is serialized for the entity). On the client-side, proxies are deserialized, operations are turned into EntityChangeEvents, and then for each invocation, depending on their success on the server, the onSuccess or onFailure of the attached Receiver is called.
There are of course additional steps for onConstraintViolations and "global failure", but you get the general idea: when you persist() a proxy, it doesn't take a snapshot of its state, it only enqueues an invocation; the state will be taken at the time you call fire(), not before.

Elhanan Maayan

unread,
Nov 30, 2011, 5:16:15 AM11/30/11
to google-we...@googlegroups.com
you mean keep a reference to ctx2 and call persist on it after the flush , becouse persist requires the proxy, i think i finally got the bit about queing, and i'm going for the edit-persist sequence, and flush-fire (which won't make much sense readability wise), but then again, neither is most of rf related code anyway.
now the real issue here is the validation handling, i understand the proper way is to catch the onConstraintViolations here:
 DRIVER.setConstraintViolations(violations);
        final List<EditorError> errors = DRIVER.getErrors();
        for (final EditorError editorError : errors) {
          final Object userData = editorError.getUserData();
          final Object value = editorError.getValue();
          System.out.println(userData);
          System.out.println(value);
        }

(because getting the errors has only after the call on flush made it.

but this still doesn't make much sense in regards to the client side validation of gwt (the "experimental" one), if i got it right, i would have to duplicate my validation annotations on to the getter of the entityProxy, and manually call the validate command on it, before i even use the flush, but then i'm back to the fact i don't have an updated entityProxy to validate against ..


--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.

Thomas Broyer

unread,
Nov 30, 2011, 5:38:42 AM11/30/11
to google-we...@googlegroups.com
RequestFactoryEditorDriver#flush simply copies the data from the widgets to the EntityProxy, so either you validate data in your widgets (calling EditorDelegate#recordError; see the ValueBoxEditor for an example) or you validate your proxy, but you'd have to flush() first so the proxy is updated.
And if you need a reference to your EntityProxy, well, just keep it one in a field of your class (this is how you'd do it anyway if you didn't use the Editors framework; what this one does is for the most part generating code for "put this object's data into the widgets" and "put the widgets' value into the object"; see https://gist.github.com/780560, compare the two commits for a "without the Editor framework" and "with the Editor framework").

Now, about JSR303 on the client-side, then yes, you'll have to put annotations on your proxies. You can see it as duplication, or as a feature in that it allows you to validate differently on the client-side and the server-side (because you don't have the same capabilities).
I believe the idea was that proxies would be generated somehow, rather than maintained by hand; and also that JSR303 support on the client-side was done without thinking particularly about RequestFactory.

Elhanan Maayan

unread,
Nov 30, 2011, 5:52:51 AM11/30/11
to google-we...@googlegroups.com
ok let's assume i'm using the server side validation ,is there any easy to get the control which has the wrong value (i'm assuming the use of path is needed) from the editorError?

--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.

Ashwin Desikan

unread,
Nov 30, 2011, 7:42:16 AM11/30/11
to google-we...@googlegroups.com, Elhanan Maayan
Yes, you can control. In your RequestFactory fire operation, override
the OnConstraintViolation method in the receiver, like below.


@Override
public void onConstraintViolation(
Set<ConstraintViolation<?>> violations) {
Iterator<ConstraintViolation<?>> itr = violations
.iterator();
while (itr.hasNext()) {
ConstraintViolation<?> viola = itr.next();
log.log(Level.WARNING,
"Violation : [ " + viola.getMessage() + ": "
+ viola.getPropertyPath() + " : "
+ viola.getInvalidValue() + " ]");
}

// set the contraints in the editor
view.getEditor().setConstraintViolations(violations);
}


Now the violations are passed onto the editor. In the editor you can
use wrap the controls which needs to display the violation messages
using the ValueBoxEditorDecorator

example :

<e:ValueBoxEditorDecorator ui:field="titleDecorator"
addStyleNames="{style.common.separator10} {style.common.txtClrRed}
{style.common.separatorT}">
<e:valuebox>
<g:TextBox ui:field="title"
addStyleNames="{style.common.textHldr}"/>
</e:valuebox>
</e:ValueBoxEditorDecorator>

Thanks
Ashwin

> <mailto:google-we...@googlegroups.com>.


> To unsubscribe from this group, send email to
> google-web-tool...@googlegroups.com

> <mailto:google-web-toolkit%2Bunsu...@googlegroups.com>.


> For more options, visit this group at
> http://groups.google.com/group/google-web-toolkit?hl=en.
>
>

> --
> You received this message because you are subscribed to the Google
> Groups "Google Web Toolkit" group.

Reply all
Reply to author
Forward
0 new messages