Passing complex parameters

Posted by Admin on 06-Feb-2013 16:46

Is it possible to build a Json object in the mobile app and pass it to the OpenEdge AppServer as a Character or Longchar with the GET REST call?

The background: In our framework we have implemented JsonSerializable objects. One of these objects contains all the data a business entity needs to perform a successful read request:

- Query String

- Number of Records

- Active Table

- Batching Context (e.g. Restart Rowid)

In a perfect world, I would write some JavaScript code (or even better use Drag and Drop in the mobile AppBuilder) to build a JsonObject with the matching properties, serialize it as a string, pass that string to the GET request in a Character variable, deserialize that object on the AppServer using our existing code to a Progress object et voila!

Or do I have to use 4 distinct character parameters here and populate them individually on the client, send them to the server and rebuild the request object on the backend using the property values from the four input parameters?

All Replies

Posted by Peter Judge on 07-Feb-2013 07:36

In a perfect world, I would write some JavaScript code (or even better use

Drag and Drop in the mobile AppBuilder) to build a JsonObject with the

matching properties, serialize it as a string, pass that string to the GET

request in a Character variable, deserialize that object on the AppServer

using our existing code to a Progress object et voila!

Or do I have to use 4 distinct character parameters here and populate them

individually on the client, send them to the server and rebuild the

request object on the backend using the property values from the four

input parameters?

No, you can do what you suggest in the first paragraph. If you look at the code snippet in one of my posts from yesterday (http://communities.progress.com/pcom/message/167878#167878), you can see that that is very doable.

Note that you can only UI-bind (if you know what I mean) one element from the right to an argument for the request. If you want to get other stuff, you will need to either use localStorage or your own JS caches/context.

-- peter

Posted by Admin on 07-Feb-2013 07:47

Thanks Peter!

So you're basically coding the Json by concatenating strings. Not nice, but certainly doable.

To make this more an integrated component (part of a UI framework ;-) ), is there a way to register such a thing as a "class" or "component" and get some more tooling support, like using drag and drop for the individual properties? Let's say I want to have a slider on the screen for the number of records and want to drag the Value property of the Slider on the NumRecords property in the FetchDataRequest Json structure?

And then for building the request parameter, is there something nicer than concatenating strings that eventually make up a valid Json? I though Json was originally a JavaScript format.

Posted by Peter Judge on 07-Feb-2013 08:01

So you're basically coding the Json by concatenating strings. Not nice, but certainly doable.

Yes, for a sample it's OK. As long as that function returns a character/string, it doesn't care how it gets built. If you look at one of the other screenshots in the thread Thomas started (http://communities.progress.com/pcom/message/167891#167891) you can see that the JS doesn't even need to be bound to a UI element.

And then for building the request parameter, is there something nicer than

concatenating strings that eventually make up a valid Json? I though Json

was originally a JavaScript format.

If you have a JavaScript object already, you can say

   JSON.stringify(myobj);

If you have a string, you can convert it to a JavaScript object via

  myobj = JSON.parse('{"prop1":"val1"}');

Some general doc at https://developer.mozilla.org/en-US/docs/JSON . stringify at  https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/JSON/stringify  and  parse at https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/JSON/parse .

To make this more an integrated component (part of a UI framework ),

is there a way to register such a thing as a "class" or "component" and

get some more tooling support, like using drag and drop for the individual

properties?

I'm not sure about customisations for the tooling.

Let's say I want to have a slider on the screen for the number

of records and want to drag the Value property of the Slider on the

NumRecords property in the FetchDataRequest Json structure?

You can do this already: on the page's components on the right-hand-side, you can select the UI component (slider in this case) , and then expand to select the attribute you want bound to a request (or response) parameter. Eg

psdn_slider.png

-- peter

Added screenshot for slider. Message was edited by: Peter Judge

Posted by Admin on 07-Feb-2013 08:08

You can do this already: on the page's components on the right-hand-side, you can select the UI component (slider in this case) , and then expand to select the attribute you want bound to a request (or response) parameter. Eg

I'm aware of that. But I don't want to map the Slider's value to a request parameter. I want to map the Sliders value to a property of a JavaScript object, that I'd stringify and then pass as a JsonString to the AppServer.

Posted by Peter Judge on 07-Feb-2013 08:09

pjudge wrote:

So you're basically coding the Json by concatenating strings. Not nice, but certainly doable.

So a more correct alternative might look something like:

var myParams = {};

myParams.rowsToBatch = value;  // assuming this is passed in because it's bound to the UI in the MAB

myParams.startRowid = localStorage.getItem('startRowid');   // like a global variable :)

myParams.whereClause = AETF.context.currentWhereClause;  // this is some JS object that's in scope

return JSON.stringify(myParams);

-- peter

Posted by Ricardo Perdigao on 07-Feb-2013 08:11

> So you're basically coding the Json by concatenating strings. Not nice, but certainly doable.

Not really.  You can have as many input/request parameters as you would like and drag and drop to them.  You would write your own class for that and use an operation type "Invoke".  For that to happen, you have to:

- Write the class with you own input/output parameters

- Use Right-click / OpenEdge / Define Services Interface to create the annotation for you class

- Save / Compile / Update Defined Services (for it to generate the project.json with your new operation)

- Re-create the JSDO Services in Tiggzi and input the new project.json (it will only import the new operation)

- Go into the Operation Settings in Tiggzi and define the response structure

One point to notice is that the response structure for an "Invoke" service is not currently auto-populated (like it is on the ones provided by Progress - ie.: read).  So you will have to tell the Mobile UI tool what you will be receiving as parameters on the response.

On Read a typical response is something like (reponse structure auto-populated when you import the project.json):

dsCustomer (dataset)

     eCustomer (temp-table) (array)

          field1

          field2

On an "Invoke" or custom class a typical reponse structure will be something like  (you have to input that information on the operations at the UI Builder):

dsCustomer (parameter name)

     dsCustomer (dataset name)

          eCustomer (temp-table)  (array)

               filed1

               field2

On the invoke, you can strucutre the input/output parameters however you like.  You don't need to pass a dataset (you can pass a temp-table) and you can have as many input parameters as you would like.

Hope this helps a little ...

Posted by Peter Judge on 07-Feb-2013 08:21

I'm aware of that. But I don't want to map the Slider's value to a request

parameter. I want to map the Sliders value to a property of a JavaScript

object, that I'd stringify and then pass as a JsonString to the AppServer.

OK. I don't believe so, not directly with the provided JSDO services.

(I have to disclaimer what comes next as being untried-by-me and so take with a pinch of salt)

But if you're feeling adventurous, you might want to 'Add Service' and select one of the generic ones. You can set up the input/output parameters for that service. That might have all of your standard rowsToBatch and startRowid and whatnot, and also (probably) a service name. You would need to write code to do the work of invoking the service. Take a look at Create New > Service > Generic (custom JavaScript implementation). In the Settings tab, you can add a custom implementation which becomes its own javascript file. In the Request and Response tabs you would add the relevant arguments.

I'd be interested in hearing how you get on with this (or whatever approach you take, to be honest).

-- peter

Posted by Admin on 07-Feb-2013 08:28

But if you're feeling adventurous, you might want to 'Add Service' and select one of the generic ones. You can set up the input/output parameters for that service. That might have all of your standard rowsToBatch and startRowid and whatnot, and also (probably) a service name. You would need to write code to do the work  of invoking the service.  Take a look at Create New > Service > Generic (custom JavaScript implementation). In the Settings tab, you can add a custom implementation which becomes its own javascript file. In the Request and Response tabs you would add the relevant arguments.

I'd be interested in hearing how you get on with this (or whatever approach you take, to be honest).

That sounds like something I might like :-)

Posted by David Cleary on 07-Feb-2013 10:13

I just wanted to point out the GET does not support a payload, so you would be required to pass this in as a query parameter. That is certainly possible, but your url will be nasty looking.

Dave

Posted by Admin on 07-Feb-2013 11:24

davec schrieb:

I just wanted to point out the GET does not support a payload, so you would be required to pass this in as a query parameter. That is certainly possible, but your url will be nasty looking.

Hi Dave, I can certainly live wit that. :-)

Posted by Shelley Chase on 08-Feb-2013 22:21

Hi Mike,

Other than defining a service, you can define local storage variables and map those to UI components in event handlers.

For more info take a look at

http://blog.tiggzi.com/2011/09/getting-started-with-html5-local-storage and

http://help.gotiggr.com/documentation/events-and-actions/actions/set-local-storage-variable

-Shelley

This thread is closed