Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    criteria for ds performCustomOperation

    Hi,
    I can't seem to figure out how to pass extra criteria arguments to a custom operation on a DataSource.

    My calls are in general:
    Code:
    ds.performCustomOperation(opID, myRecord, callback, requestProps)
    and on the server:
    Code:
    public DSResponse operation(DSRequest dsRequest) throws Exception
    dsRequest.getValues() holds the myRecord, which I'm transforming to a server object using DataTools.


    I can't seem to pass anything with the requestProps (a DSRequest object) though (for example a non-data parameter for the server call).

    Example pass key "hello" and value "hi" from client to custom operation:
    If I do requestProps.setAttribute("hello", "hi"), where should I be able to find that attribute in the server?

    If I put ("hello", "hi") in the myRecord, I do find it on the server, but this sits
    in between my record attributes and DataTools gives me a correct warning
    Code:
    setProperties: couldn't set:
    {
        hello:"No such property"
    }
    so I don't want to use this.

    I saw dsRequest has a call getAttribute(), but what does it do? Also inspecting the dsRequest "attributes" field in debug mode shows it's always empty. Can I use that to pass something?



    So in a general note, should the Criteria functionality be possible here?
    I saw this note though on dsRequest.getCriteria - not be used with a custom operation.
    Code:
         * Return the Criteria associated with a FETCH operation.
         * <p>
         * <b>Note</b> : This method should only be called during a FETCH operation

    #2
    You're talking about criteria and various dsRequest API related to criteria. If this operation is essentially a fetch, don't use performCustomOperation, just create an operationBinding with operationType:"fetch" and a different operationId, and call it via DataSource.fetchData().

    In general, performCustomOperation() is a rarely used API, the most common use would be for a SQLDataSource where you want to perform a customSQL operation that is not really a fetch, add, update or remove.

    Comment


      #3
      But is it possible to pass extra arguments to a custom operation?

      I don't use a sql backend, but a java backend which does some business logic. There are calls get() and set() which are mapped to the SmartClient 'fetch' and 'update' types in a DataSource, but to execute custom business logic I thought to use the SmartClient 'custom' operationType.

      Let's say "cancel an order on a specific date": cancel(Order, Date) would be a custom operation on datasource OrderDS. The user should specify his own Date in the client, which is not an attribute of the Order record.

      So if I can't use the 'custom' type for this, do I need to program just 1 fetch operation which checks the operationID passed and on the server do things like
      Code:
      if (operation == 'get') {
      //do real fetch
      } else if (operation == 'cancel') {
      //do cancel operation
      } else if (operation ...

      I ultimately want to use the operationBindings in the DS and use the cool SmartClient server feature which can pass the correct value to the correct argument in my server call by inspection, without me doing all that work manually in each method:
      Code:
      public DSResponse cancel(SecurityToken token, DSRequest dsRequest, Order order, Date dateToCancel) throws Exception {
      server.cancel(token, order, dateToCancel)
      }
      versus
      Code:
      public DSResponse cancel(DSRequest dsRequest, Map values) throws Exception {
      token = Tools.getToken(dsRequest);
      order = DataTools.setProperties(values, order);
      dateToCancel = dsRequest.getCriteria("dateToCancel")
      server.cancel(token, order, dateToCancel)

      Comment


        #4
        Again, custom operations are rare. Think about your use of canceling an order - if orders were display in a grid, what should happen in the UI when the order is canceled? It would either be a "remove" (if canceling just deletes the order outright) or an "update" of the status field (if it just changes status to canceled but is retained for record-keeping.

        Represent any given operation as the nearest CRUD type (fetch, add, update or remove) unless it truly has nothing to do with CRUD at all.

        Comment


          #5
          So I'm trying this out... converting calls to 'fetch' where I used 'custom' before.

          Here's what I was thinking, but doesn't work:
          Code:
          criteria.setAttribute(parameter1, value1);
          criteria.setAttribute(parameter2, value2);
          requestProperties.setData(record);
          ds.fetchData(criteria, callback, requestProperties);
          If I do this, the RPCRequest in the devconsole shows the structure "data" containings an object "criteria" containing the record from data, my parameters don't get sent in the request. I guess they are overwritten by the setData call?
          I did expect a bit to have separate structures "data" and "criteria".


          Note that "record" is a DTO which will be converted with the DataTools to a serverobject and value1 & value2 are just method parameters on the server call.

          Do I need to remove the requestProperties.setData(record) and pass the record also as a criterium?
          Can I still use the SmartClient server magic thing which can separate the parameters from the actual server object in the server call (I think I tried it before mentioned in this thread)?

          Comment


            #6
            Use addCriteria(), not setAttribute.

            Do not setData on the requestProperties. It's a fetch, so it expects criteria. Send criteria only, or use a different operationType (update, add, remove) if it's not really a fetch. Recall:

            Represent any given operation as the nearest CRUD type (fetch, add, update or remove) unless it truly has nothing to do with CRUD at all.

            Comment


              #7
              Maybe an updateData method would be more logical here instead of fetch if you view it from the SmartClient framework (though update doesn't make sense from our server's point of view), but also with updateData I cannot send the parameters together with the record data.

              Comment


                #8
                It's not SmartClient / SmartGWT imposing a special perspective here, it's just what the client system (any client system) is supposed to do when the operation completes.

                updateData takes a Record - you can put whatever attributes you want in that record.

                Comment


                  #9
                  I got this working like this:

                  client
                  Code:
                  DSRequest requestProperties = new DSRequest();
                  requestProperties.setOperationId("myoperation");
                  LinkedHashMap<String, String> ourCriteria = new LinkedHashMap<String, String>();
                  ourCriteria.put("arg1", formfield.getValue().toString());
                  requestProperties.setParams(ourCriteria);
                  
                  vm.saveData(new DSCallback() {
                  	
                  	@Override
                  	public void execute(DSResponse response, Object rawData, DSRequest request) {
                  		
                  	}
                  }, requestProperties);

                  and I get the records as-is on the server fine in the data where I expected them to be,
                  and I can get my extra arguments with this:
                  Code:
                  Object value = dsRequest.getRequestContext().request.getParameter("arg1");

                  Comment

                  Working...
                  X