Announcement

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

    velocity #foreach does not seem to work

    Hello,

    I am using the following
    SmartClient Version: v8.3p_2013-04-19/PowerEdition Deployment (built 2013-04-19)

    With firefox 17.0.1

    I am using Smart GWT and MySQL.
    I have some .ds defined that are using velocity.

    However, I need to write a more tricky query. One that
    loops over a list of values and does a union on the query.

    It does not seem that #foreach is supported by velocity with Smart GWT.
    Can you give me an example of a legal #foreach with smart gwt?

    Thanks,
    Evan

    #2
    #foreach works normally - just use the Velocity reference.

    However for more complex logic we generally recommend doing it in Java, and using dsRequest.addToTemplateContext() to make the final SQL (or some intermediate processing result) available to SQL Templating.

    Comment


      #3
      how to pass array?

      Hello,

      I can't seem to pass an array.

      I can certainly define a GWT array of string values.
      Is this the $aValues I should be looping over?
      But the example looks like javascript objects in the array.
      Do you have an example of Smart GWT making some array and then using that in velocity?

      Thanks,
      Evan

      http://velocity.apache.org/engine/releases/velocity-1.5/user-guide.html#loops

      has the example
      <ul>
      #foreach( $product in $allProducts )
      <li>$product</li>
      #end
      </ul>

      or the example
      <table>
      #foreach( $customer in $customerList )
      <tr><td>$velocityCount</td><td>$customer.Name</td></tr>
      #end
      </table>

      Comment


        #4
        Sorry, we can't figure out your question.

        This is a server-side subsystem, you would not be creating an Array of String in GWT, but in server-side Java. Then you would call dsRequest.addToTemplateContext() *on the server* and use #foreach with that Array.

        Comment


          #5
          let me try again

          Hello,

          I am on the client side.
          I am in Smart GWT java
          I want to bind a variable to an array of strings.
          And then iterate over these values using the #foreach in my
          .ds.xml file (using velocity).
          Where (and how) do I define such a variable?

          I would like to pass an array of strings now.
          How do I "bind a variable" in the client that I can then use in velocity.

          His is a sample of some velocity I have, perhaps it will help.

          Thanks,
          Evan

          sample sql
          Code:
          <operationBinding operationId="opIDSearchMe" operationType="fetch">
            <customSQL>
            
              SELECT DISTINCT rvi_today.drug,
                 rvi_today.ind,
                 rvi_today.company,  
                 rvi_today.entfieldskey,
                 rvi_today.phaserank,
                 #if ($advancedCriteria.company)
                  drug_ind_company.q5company as q5,
                 #elseif ($advancedCriteria.target)
                  drug_ind_target.q5target as q5,
                 #elseif ($advancedCriteria.drug)
                  rvi_today.q5drug as q5,
                 #else
                  rvi_today.q5ind as q5,
                 #end
                          
                 rvi_today.devdrindphase,
                 rvi_today.ravi
            FROM relaybdlive.rvi_today rvi_today
            #if ($advancedCriteria.target)
          ...

          Comment


            #6
            some things I have tried

            On the client side I have tried the following to pass some array (or map) from the client to sql. None seems to allow me to do a #foreach on them.

            None of the following seem to have an array type for the .setData
            So tried a map. But really just want to pass an array of strings.
            And then use the #foreach to run a query and union the results. I intend to vary one of the arguments in the sql based on the iterator.


            Code:
            Map<Integer, String> params = new HashMap<Integer, String>();
            		params.put(1, "Warfarin");
            		params.put(2, "Tylenol");		
            		dsRequest.setData(params);
            or tried

            Code:
            Map<Integer, String> defaultParams = new HashMap<Integer, String>();
            				defaultParams.put(1, "Warfarin");
            				defaultParams.put(2, "Tylenol");
            				ds.setDefaultParams(defaultParams);

            Comment


              #7
              Params are HTTP params, which generally are not array-valued.

              You've been vague about the overall use case, which makes it difficult to recommend any particular approach, but one approach to passing an Array to the server is to make it an attribute of a Record, and pass that Record to the server via DataSource.performCustomOperation(). Then the array will be available as $values.attributeName.

              Comment


                #8
                ok

                Hello,

                Thanks for sticking with me. Sorry to be vague.

                I am trying to iterate over a list of strings in a mysql query. The strings are defined in the client. I have the attached .ds.xml with a custom query and the #foreach as shown.

                I have attached a "log" of the data I am passing back.

                I have been using the criteria to pass values back, and ignoring the operation as I am doing a custom query.

                I am able to get the array of values back to the .ds.xml
                And if I don't use the #foreach and just pass one value then the query does generate legal SQL.

                However, with one values in my array and now using the #foreach I get an empty query back.

                How do I debug the query that is generated incorrectly? Or perhaps the #foreach can't access the values?

                I will look at trying the data source approach you have suggested.

                I understand I am likely violating lots by passing values this way. But I did not know how else to get values back.

                Evan
                Attached Files

                Comment


                  #9
                  Start by providing this log first next time (the forums prompts you to always provide it). It reveals all kinds of key details that would allow us to immediately respond with useful information instead of having to speculate for several turnarounds.

                  First one being: your AdvancedCriteria is invalid. The "equals" operator cannot be provided an Array as the value. "isOneOf" does take an array value.

                  Second, it may be that $advancedCriteria has an issue where it can't return Arrays - we'll check on this - but if so, you can get around this by retrieving the Array value in Java (use dsRequest.getCriterialValue("arrEnt")) and providing it to the Velocity context separately (use dsRequest.addToTemplateContext()).

                  Comment


                    #10
                    ok

                    Hello,

                    So I can't pass my array of strings using criteria. And am trying to pass it on the dsRequest as described. But ...

                    I don't seem to have any add methods on
                    my dsRequest object.

                    In my java code I do the following
                    include com.smartgwt.client.data.DSRequest;
                    DSRequest dsRequest = new DSRequest();
                    lg.fetchdata(critEntityGrid, callback, dsRequest);

                    Evan

                    PS bet there is an isomorphic version of this and I am including from the wrong place. how could that be happening?

                    Comment


                      #11
                      You can pass array values in criteria (re-read previous post).

                      Server-side classes are com.isomorphic.*, client-side classes are com.smartgwt.*. The APIs we referred to (addToTemplateContext() for example) are server-side APIs.

                      Comment


                        #12
                        includes

                        Hello,

                        Well if I change my DSRequest to include from
                        import com.isomorphic.datasource.DSRequest;

                        Then I have the .add

                        However, then my fetch does not work
                        listGrid.fetchData(critEntityGrid, callback, dsRequest);
                        as I am including my list grid from

                        import com.smartgwt.client.widgets.grid.ListGrid;

                        And these two includes do not seem to play nice.

                        Ideas?

                        Evan

                        Comment


                          #13
                          It seems you may need to return to the QuickStart Guide and review the Server Framework chapter, especially the Server Request Flow section - you don't seem to have a clear concept of processing order here, and you seem to think you can write server and client code in the same file (you can't).

                          Comment


                            #14
                            hmm

                            Hello,

                            I am not writing server and client code in the same file.

                            Everything works just fine, until I tried to use foreach.

                            So my question remains.

                            Evan

                            Comment


                              #15
                              ???

                              You just said you tried to include com.isomorphic.datasource.DSRequest in some code where you are calling listGrid.fetchData(). That is trying to use server and client code in the same file.

                              To write the server code we're telling you that you need, you will need to add a DMI or use one of the other approaches discussed in the QuickStart Guide for adding server-side logic.

                              Comment

                              Working...
                              X