Greetings!
In the Walk Through Tutorials, Step by Step, Creating a JSON REST Service, Step 4 - Accepting JSON parameters:
The suggested code in the CustomerRestService.prg for customers is as follows:
************************************************************************
* Customers
****************************************
FUNCTION Customers(loFilter)
lcWhere = ""
IF !ISNULLOREMPTY(loFilter)
IF !ISNULLOREMPTY(loFilter.FirstName)
lcWhere = "FirstName = loFilter.FirstName AND "
ENDIF
IF !ISNULLOREMPTY(loFilter.LastName)
lcWhere = lcWhere + "LastName = loFilter.LastName AND "
ENDIF
IF !ISNULLOREMPTY(loFilter.Company)
lcWhere = lcWhere + "Company = loFilter.Company AND "
ENDIF
ENDIF
IF !EMPTY(lcWhere)
lcWhere = "WHERE " + RTRIM(lcWhere,"AND ","OR ")
ENDIF
SELECT id,FirstName,LastName,Company,Entered FROM Customers ;
ORDER BY Company ;
&lcWhere ;
INTO CURSOR TCustomers
Serializer.PropertyNameOverrides = "firstName,lastName"
RETURN "cursor:TCustomers"
The problem I am having is how do I pass these JSON parameters in the URL? The walk thru shows how to test this in West Wind WebSurge, but I just don't see it! Where/how are the parameters getting passed in?
Thanks, Scott M.
I have not looked at the current tutorials but I can tell you in hte code you show, loFilter should contain the JSON data.
On the other hand, if you are asking how to pass this data back to the server, you could try calling your method like the following:
http://yourDomain.com?Customers&{"lastname":"Strahl"}
I suspect this will give you a jump off point.
I'm sure Rick will have a better example...
To test you'll need some sort of HTTP client to connect to it and POST the data.
In WebSurge you add the post data to the content body and set the operation to POST. The content payload is json in this case.
{
FirstName: "Rick",
LastName: "Strahl",
Company: "West Wind"
}
Here's what it looks like in a request (in WebSurge):
If you want to also handle query string parameters (ie. "firstname=Rick" on the url) you have to manually handle that, but that's not the way this is meant to work in this case. Since it's an API it's not meant to be accessed directly from the browser, but through an API.
+++ Rick ---
Rick,
Thanks for the clarification. I am not "savvy" in these areas at all, so it will take me awhile to make it work. But, at least I know what path to take.
Thanks,
Scott
Harvey,
Thanks for your input. I appreciate it. I did apply what you suggested in the URL, but the parameters were not making it all the way to the Customers function for some reason. I believe Rick's answer below helps as you suggested
Thanks Harvey,
Scott
Rick,
It took some reading and some trial and error. But, I did get it to work based on the information you presented in Step 6 of your walk thru. So many new things and so little time
And, it worked beautifully!
Next...Accessing the REST API with jQuery and Angular.
Thanks Rick and Harvey!!
Scott M.
Parameters can be passed on the URL using Parm1, Parm2, Parm2 syntax.
But it has to be in the right format - if the request is expecting JSON then you'd have JSON on the URL which is just not something you should ever do. When you send data to the server use POST or PUT verbs to do so - not the query string. Querystring parameters should be limited to Ids or operational switches, or things like simple search terms perhaps, but never full sets of data.
+++ Rick ---
Rick,
Good point and well taken!
The problem I have identified here stems from the Step by Step bu Step: Creating a JSON REST Service, Step # 8 - Accessing the REST API with jQuery.
I am doing just what you stated, passing the ID in the URL (per the provided step by step code ). It fails on the retrieval of the individual customer records because the query string ID is not making it to the processing VFP code?
Here is the JS code :
getCustomer: function getCustomer() {
var id = $("#CustomerList").val();
if (!id) {
toastr.warning("Please select a customer.");
return null;
}
return $.getJSON("customer.csvc?id=" + id)
.success(function (cust) {
page.activeCustomer = cust;
toastr.success("Customer loaded:<br/> " + cust.company);
var template = $("#CustomerTemplate").html();
var html = parseTemplate(template, cust);
$("#CustomerContainer").html(html).show();
})
.error(function (err) {
toastr.error("Customer was not retrieved.");
});
I'm having difficulty getting access to the ID being passed in the line: return $.getJSON("customer.csvc?id=" + id)
I have a customerRestService.prg that has the code for the customer.csvc request:
******************************************************************************
*!* Customer - get single customer by ID using Request
******************************************************************************
FUNCTION Customer()
lcWhere = REQUEST.QueryString("ID")
SELECT ID,FirstName,LastName,Company,entered FROM Customers ;
WHERE ID = &lcWhere ;
INTO CURSOR TCustomer
Serializer.PropertyNameOverrides = "firstName,lastName"
RETURN "cursor:TCustomer"
ENDFUNC
The lcWhere variable always returns blank. I have ran this through the debugger and tried to figure it out and I just can't do it! Any thoughts on why the query string is not making it all the way to the VFP code?
Thanks,
Scott M.
Hi Scott,
did you check the query string?
FUNCTION Customer()
assert !empty(REQUEST.QueryString())
lcWhere = REQUEST.QueryString("ID")
Hi Thierry!
In the VFP debugger, In the watch section: !empty(REQUEST.QueryString()) returns (Expression coud not be evaluated)?
However, REQUEST.cQueryString returns "id%20=%20_4FG12Y7U6", which is what I am looking for (or at least in the rough form of what I am looking for)! I just want the "_4FG12Y7U6" value.
Any thoughts on that?
Thank you!!
Scott M.
IMO, id%20=%20_4FG12Y7U6
should be URLdecode()
d, like this: id = _4FG12Y7U6
IOW, without %20
That certainly gets the data into the right format.
Thanks for the tip!
You've got spaces on the query string (%20
) for the key field which is invalid. Remove the spaces (which are invalid for query strings and for sure of the key value which has to be id=
not id =
to be found).
Request.QueryString('id')
is what you should be looking at and that should work as long as you have a valid query string that includes an id
key (without spaces).
+++ Rick ---
Rick,
That worked...now, on to the next issue. I am in An Introduction to Angular Js, Step #3 (2nd one) Getting Todo Data from the Web Connection Server.
In the Retrieving the Todos From the Server - Take 1 section: ...add a function called loadTodos() like this:
// Interface function implementations
function initialize() {
loadTodos();
}
function toggleCompleted(todo) {
todo.completed = !todo.completed;
}
function buttonClick() {
vm.message = "Curious little bugger are you? Good! Updated time is: " + new Date();
}
// in implementation section
function addTodo() {
// copy the todo - important!
var td2 = $.extend({}, vm.activeTodo);
// and add it to the model array
vm.todos.splice(0, 0, td2);
// clear out the form values
vm.activeTodo.title = null;
vm.activeTodo.description = null;
}
function loadTodos() {
$http.get('todos.csvc')
.success(function (todos) {
vm.todos = todos;
})
.error(parseHttpError);
I'm getting this error: ReferenceError: parseHttpError is not defined
What have I missed?
Thanks,
Scott M.
parseHttpError
lives in the ww.angular.js
javascript library in your scripts folder most likely. You need to add that to the page.
Otherwise you can just put a custom error handler there.
+++ Rick ---