How to pass parameters to the ABL Class?

Posted by curtiscooper on 20-Oct-2017 14:49

I have a gridview in Kendo UI Builder, and I want to pass parameters to the Read method which is setup to accept a "filter" parameter. 

The data source is set for Client Side Processing, which is what I want, but I want to start with a subset of data using an initial filter value. 

I have disabled autobind, so the gridview isn't initially pulled

   in onShow - this.$components.psLogGrid.options.autoBind = false;

I have a text fill in and a button which runs the javascript below which I want to pass in to the Read method in ABL Class.

However, the value filter in the browser is "Object", and the value in the Read method is ? 

Does anyone know how to do what I thought would be a simple process of passing in a parameter to the Read method? Perhaps I am setting the value of filter incorrectly below? 

Thanks for your help.

// Fired when user selects the button. tbProcess is the name of the text fill in, and I have validated angular.element('#tbProcess').val(); is the correct value that I want.

    filterByProcess($scope) {
                    
                debugger;
                
        var dataGrid = this.$components.psLogGrid.widget;     
        var value = angular.element('#tbProcess').val();

        console.log("value " + value);

        if (value) {
                     var filter = {
                                        logic:'and',
                                        filters: [
                                                { field: 'processName', operator: 'contains', value: value }
                                        ]
                        };
                        this.$ds['psLog'].filter(filter);
        } else {
                        this.$ds['psLog'].filter({});
        }

    
             console.log("Filter - " + filter);   
        
    }

All Replies

Posted by egarcia on 21-Oct-2017 08:03

Hello,

> I have a gridview in Kendo UI Builder, and I want to pass parameters to the Read method which is setup to accept a

> "filter" parameter.

Are you using a custom data source?

How does your data source definition look like?

Please notice that for a data source of type "jsdo", the read operation is handled internally.

Also, if what you intend to send is a filter, then the data source should be configured with serverFiltering: true for the filter to be sent to the remote service.

Perhaps, the following post in the Kendo UI forum helps:

www.telerik.com/.../datasource-read-with-parameters

I hope this helps.

Posted by egarcia on 21-Oct-2017 08:51

Hello,

Sorry for the confusion in the previous post. I thought that you wanted to send custom parameters while working with Client-side Processing.

I now see that you are actually using a data source for an OpenEdge Business Entity and pass a filter to its Read method.

To pass a filter to the Read method, you would configure your Business Entity to use what we call the JSON Filter Pattern (JFP).

You would also need to de-select "Client-side Processing" in your Data Source configuration (Data Provider / Data Sources). In this way, the the data source would use server-side processing and pass the filter to the backend.

The enable your Business Entity for JFP you need to do some few changes in the Business Entity:

- enhance the temp-table definition

- add the mappingType and capabilities annotation to the Read method

- add the corresponding code to for the Read and JFPFillMethod methods

- add a method to do count (to support paging)

Here is a link to a sample implementation:

documentation.progress.com/.../index.html

I hope this helps,

Edsel

Posted by curtiscooper on 23-Oct-2017 10:22

Thanks Edsel. I followed the steps to use JFP, and I get a error invoking MyCount when I have more than about 5 records. I am trying to figure that out in a separate project. For this, I want to use Client Side processing, but I want to pass in initial parameters to retrieve a subset of data to start with, not ALL of it. This particular project DOES use a custom data source built from my Temp Table. The Read class seems setup to accept parameters with the FILTER parameter, but whether I use that or not, there MUST be a way to pass in parameters to the Read class using Client Side; isn't there?

Posted by egarcia on 23-Oct-2017 10:59

Hello  Curtis,

Thank you for the additional information.

What error do you get with the MyCount?

In your custom data source, are you using the transport.read method?

> The Read class seems setup to accept parameters with the FILTER parameter, but whether I use that or not, there

> MUST be a way to pass in parameters to the Read class using Client Side; isn't there?

A key thing here is that when you use client-side filtering, then the Read method in the Business Entity does not get the filter.

An alternative to pass additional parameters, would be to set custom parameters that would be sent to the server at the time of the READ operation.

This can be done by using a custom mappingType plugin.

The following article in the documentation provides information on such a plugin "MYJFP" to send a "mydata" parameter:

documentation.progress.com/.../index.html

Note: The mydata parameter can be of any type.

In the Business Entity using "MYJFP", you would use something like the following:

  mydata      = jsonObject:GetCharacter("mydata") NO-ERROR.

Please check this article and let me know if you need additional information or samples.

I hope this helps.

Posted by curtiscooper on 23-Oct-2017 11:39

Thanks. I will check out that link. If I could pass in parameters and do client side processing, that would be ideal. I am not sure on the transport.read method. I didn't do anything custom with that ; I just have the class generated when creating an ABL Web App project in PDSOE.

I am going over the JSD setup again to see if I missed something. The error I get in when doing server side is :

Failed to load resource: the server responded with a status of 404 ()

progress.all.js:12498 [Deprecation] Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.

progress.data.AuthenticationProvider._openRequestAndAuthorize @ progress.all.js:12498

:8810/psLogGUI/rest/psLogGUIService/psLogDtl/MyCount?filter=%7B%22skip%22%3A0%2C%22top%22%3A5%7D&_ts=150834865-6640993464-4 Failed to load resource: the server responded with a status of 404 ()

Link failing

localhost:8810/.../MyCount

localhost_access-log : shows 404 error, but it tells me nothing

0:0:0:0:0:0:0:1 - - [18/Oct/2017:13:44:22 -0400] "OPTIONS /psLogGUI/rest/psLogGUIService/psLogHdr/MyCount?filter=%7B%22skip%22%3A0%2C%22top%22%3A5%7D&_ts=150834865-6640993464-5 HTTP/1.1" 200 - 1

0:0:0:0:0:0:0:1 - - [18/Oct/2017:13:44:22 -0400] "PUT /psLogGUI/rest/psLogGUIService/psLogHdr/MyCount?filter=%7B%22skip%22%3A0%2C%22top%22%3A5%7D&_ts=150834865-6640993464-5 HTTP/1.1" 404 - 32

0:0:0:0:0:0:0:1 - - [18/Oct/2017:13:44:22 -0400] "PUT /psLogGUI/rest/psLogGUIService/psLogDtl/MyCount?filter=%7B%22skip%22%3A0%2C%22top%22%3A5%7D&_ts=150834865-6640993464-4 HTTP/1.1" 404 - 34

0:0:0:0:0:0:0:1 - - [18/Oct/2017:13:44:22 -0400] "OPTIONS /psLogGUI/rest/_oeping?_ts=150834865-6640993464-6 HTTP/1.1" 200 - 0

0:0:0:0:0:0:0:1 - - [18/Oct/2017:13:44:22 -0400] "GET /psLogGUI/rest/_oeping?_ts=150834865-6640993464-6 HTTP/1.1" 200 39 12

0:0:0:0:0:0:0:1 - - [18/Oct/2017:13:44:22 -0400] "OPTIONS /psLogGUI/rest/_oeping?_ts=150834865-6640993464-7 HTTP/1.1" 200 - 1

0:0:0:0:0:0:0:1 - - [18/Oct/2017:13:44:22 -0400] "GET /psLogGUI/rest/_oeping?_ts=150834865-6640993464-7 HTTP/1.1" 200 39 5

If I only have a few records, it works. However, I assume this is only because there are few enough records such that myCount function is not running.

Posted by egarcia on 23-Oct-2017 12:27

You are welcome.

Yes, there is an optimization that the count method is only called if the number of records is larger than the page size.

The 404 error sounds like service has not been updated with the new method.

It sounds like the catalog was updated, however, just in case, you may want to check that the catalog has the definition for the MyCount method.

Please let me know how it goes with the MYJFP/mydata approach.

Thanks.

Posted by egarcia on 23-Oct-2017 12:27

You are welcome.

Yes, there is an optimization where the count method is only called if the number of records is larger than the page size.

The 404 error sounds like service has not been updated with the new method.

Also, it seems that catalog was updated, however, just in case, you may want to check that the catalog has the definition for the MyCount method.

Please let me know how it goes with the MYJFP/mydata approach.

Thanks.

Posted by curtiscooper on 23-Oct-2017 13:53

The catalog includes the MyCount function:

                   {

                       "name": "MyCount",

                       "path": "\/MyCount?filter={filter}",

                       "useBeforeImage": false,

                       "type": "count",

                       "verb": "put",

                       "params": [

                           {

                               "name": "filter",

                               "type": "QUERY"

                           },

                           {

                               "name": "numRecs",

                               "type": "RESPONSE_BODY"

                           }

                       ]

                   }

               ]

           },

I compiled the classes and republished, but I am not sure how to check if the MyCount exists in the service or not. This is the URL that is failing (from Google Inspect) :

localhost:8810/.../MyCount

Does the big crazy filter value look correct?

Posted by Dustin Grau on 23-Oct-2017 14:24

"I am not sure how to check if the MyCount exists in the service or not."

Let's try this...

1) Download the catview.html file at this location: raw.githubusercontent.com/.../catview.html

2) Copy that file into your project's PASOEContent/static/ directory and allow PDS to publish to your PAS instance.

3) Visit the page (should be accesible at localhost:8810/.../catview.html)

4) If the page cannot self-detect the proper catalog URL, then provide te direct path to your .JSON catalog file. Based on the URL you provided, I would guess it to be this: localhost:8810/.../psLogGUIService.json

5) Press the "Load Catalog" button and you should get back a visual representation of your data object catalog. From here you can locate the MyCount method in the psLogHdr service, and execute a request against that endpoint.

Posted by curtiscooper on 23-Oct-2017 15:06

I looked at the MYJFP/mydata approach, but I couldn't determine what to put where. Also, I wonder after the initial load, how would I make a server call again from the UI.... So, for now I think I will pursue getting this to work using the Server Side processing.

Posted by curtiscooper on 23-Oct-2017 15:11

Dustin,

Thanks. That is handy! I see the MyCount function there, and selecting Sample Code and Run API works, it doesn't display anything though. It loads this URI

localhost:8810/.../MyCount

If I put the Kendo UIB generated filter in, it doesn't work:

localhost:8810/.../MyCount

I am not sure what to put in the filter to test it, but it looks like the Kendo UIB generated filter is incorrect.

I went back through the documentation on setting up JFP, and I didn't find any errors. I noticed, however, a note at the bottom: Note: If you do not add a method like this to the Business Entity and annotate it (in Developer Studio) as a Count operation, the JSDO throws an exception when the Kendo UI DataSource tries to reference the method as part of reading a server page.

I DID add a method to the Business Entity (class), but I am not sure what it means by "annotate it". Maybe I missed something?

Posted by Dustin Grau on 23-Oct-2017 15:22

When running the sample code, you should be executing the MyCount method as an "invoke" type operation. This uses the verb PUT by default and all data is sent in the request body. Therefore, the sample data to send would be a JSON object with any parameters nested within it. Though also by default these invoke methods expect a "request" wrapper and will return data inside of a "response" wrapper. Essentially, this would be the correct/expected sample data:

{

  "request": {

    "filter": ""

  }

}

I believe if you try without any filter value (leave as blank "" string) you should at least get something back. If that works, then you can try adding additional values into the filter property.

Posted by curtiscooper on 23-Oct-2017 15:29

Ok, so the long string from Kendo UIB is JSON and not incorrect?

I tried the sample, and it converted it to :

localhost:8810/.../MyCount

This results in a blank page, but no error.

Posted by Dustin Grau on 23-Oct-2017 15:38

The string from the catview.html is certainly JSON, and I was providing context on that to test that the method returns something usable and hopefully accurate without bringing KUIB into the equation (at least not just yet). Unfortunately, the URL you provided doesn't display correctly here in the forum for me to see what is being passed. If you use the catview screen, can you provide the request and response data here instead of a URL?

Posted by curtiscooper on 23-Oct-2017 15:54

I put in request what you suggested,

{

 "request": {

   "filter": ""

 }

}

And I get nothing in Response.

When I put this in postMan, I get 404 error:

localhost:8810/.../MyCount

Posted by egarcia on 23-Oct-2017 16:36

If you see nothing in Response Data in the Catalog Viewer, then it would mean that the invoke operation failed.

The Network tab in the Developer Tools in web browser would also show that a 404 error happened internally.

Note: The Network tab would also show the details of the request. You would see there that the filter is set to something like:

{"skip":0,"top":5}

In the URL, you see the encoded representation.

The 404 error would mean that the deployed service does not have the method or an error happened on the server side.

You can check the following files:

1) oepas1/webapps/psLogGUI/WEB-INF/adapters/rest/psLogGUIService/stagingDir/resourceModel.xml file: This file should have a reference to the MyCount path.

2) oepas1/logs/oepas1.agent.log: In this file, you should see whether there were errors while executing the method in the Business Entity. You can add MESSAGE statements to the Business Entity class for additional debugging.

If would like to have someone look at this environment with you, perhaps, you could contact Technical Support to get assistance and look at the issue via screen sharing. I can also join to see the issue and provide suggestions.

I hope this helps.

Posted by jts-law on 23-Oct-2017 16:37

Curtis,

I just tested one of my services with PostMan and it works correctly to get 25 records, skipping the first 50.

PUT: [URL to Service]/count

Content-Type: application/json

Body:

{

"filter": "{\"skip\": 50, \"top\": 25}"

}

To apply this filter to the GET I used the following URL to get 5 records starting with the first:

[URL to Service]/?filter=%7B"skip"%3A0%2C"top"%3A5%7D

To return 10 records, skipping 15, use the following:

[URL to Service]/?filter=%7B"skip"%3A15%2C"top"%3A10%7D

Hope this helps.

Louis

Posted by curtiscooper on 24-Oct-2017 10:23

I tried the following in Postman

PUT  localhost:8810/.../MyCount

Form data: Key Content-Type   Value: application/json

Body (raw)

{

"filter": "{\"skip\": 50, \"top\": 25}"

}

And, I get  -  404 Not Found

If I do PUT  localhost:8810/.../MyCount

 with no other parameters I get 404 Not Found

If I do GET

localhost:8810/.../psLogHdr

I get all the records

I have verified MyCount is in the Catalog and shows up using the catview.html tool.

Posted by egarcia on 24-Oct-2017 11:03

Please notice that filter is a query string parameter and would not go in the body of the request.

Could you check that the there is a reference to MyCount in the resourceModel.xml?

Do you see any errors in the agent log file?

Posted by Dustin Grau on 24-Oct-2017 11:12

Sorry about that Edsel. I just took a look at the way KUIB (more accurately the JSDO) sends the criteria for the count method, and I didn't realize that it sends the values as URL parameters and not via the body. I assumed wrongly based on the fact that this was a PUT rather than a GET (as used by the read method for a resource).

Posted by curtiscooper on 26-Oct-2017 11:41

As I mentioned on the phone, I tried making a brand new project, added the JSP stuff, and added the resource to the service, and again, MyCount is NOT added to C:\OpenEdge\WRK\oepas1\webapps\psLogGUI\WEB-INF\adapters\rest\psLogGUIService\stagingDir

resourceModel.xml

I am thinking of trying rebooting my PC and try again and/or remove all services and try again. Other than that, reinstalling Progress is the next thing I would try. Any suggestions?

Posted by Ricardo Perdigao on 26-Oct-2017 11:58

Curtis,

A reboot wouldn't hurt, but I am not confident it will address your problem.  The PDSOE team has this as a bug and has supposedly fixed it on OE 11.7 Service Pack 2.

Service Pack 2 release target is end of October (early next week if all goes well).  Would be possible for you to hold until it is release? I believe the best path would be install the Service Pack 2 (instead of re-installing your current OE).  

I would keep monitoring it for you and let you know as soon as it is release.  I would also schedule a call to help you install and test the outcome.

Please let me know if this is acceptable,

Regards,

Ricardo Perdigao

Posted by curtiscooper on 26-Oct-2017 12:12

Ricardo, Thanks. Yeah, I will standby and wait for SP 2 for Server Side work. In the meantime, I may go try to figure out how to pass parameters using Client Side processing. Any how Tos or examples on that would be appreciated.

This thread is closed