I have an existing CFC that works fine when passing structures into the method.
The problem is, we also now need to pass data into the same function via JSON.
Here is the CFC snippet:
<cffunction
name="subscribeAPI"
access="remote"
returntype="struct"
returnformat="json"
output="false">
<cfargument
name="structure"
type="struct"
required="true"
hint="data structure received from call">
<cfif StructKeyExists(arguments.structure, "listID")
AND len(arguments.structure.listID)>
...
</cfif>
<cfreturn LOCAL />
Here is how we pass in the structure:
<cfset preStruct = {
apiAction="Create",
listID="1463",
email="#form.cartEmail#",
firstname="#form.first_name#",
preCart="#now()#",
planDescription="#application.name.site#"
}
/>
<cfscript>voidReturn = application.goxObj.subscribeAPI(preStruct);</cfscript>
Now, we also need to pass in the following but are obviously getting errors due to the CFC expecting a structure:
function HandleSubscribe(){
$j.getJSON(
"/com/list.cfc?wsdl",
{
method : "subscribeAPI",
action : "Create",
listID : $j( "#listID" ).val(),
triggerKey : $j( "#triggerKey" ).val(),
email : $j( "#emailNL" ).val(),
firstname : $j( "#firstnameNL" ).val()
},
handleSubscribeCallback
);
}
How can we successfully pass in the getJSON snippet?
Thanks.
JSON is just a string, so you need to “handle” the method call before it reaches your actual service layer.
Danimal is right in that what you need to do is create a web service layer wrapper around your service.
So your service method looks like this :
Your subscription API looks like this :
So you push the JSON at the subscribe API, which converts the data to a struct and makes sure you have all the right data available and passes it off to your subscription service. The createSubscription method in the subscription service checks to see if the listid exists and checks to see if the person is already subscribed. If the list is good and the subscription doesn’t exist, insert the new subscription into the database, otherwise return results that indicate what went wrong in a struct to your API layer, which converts it to JSON and returns it.
The benefit to this is you can re-use the services in your application without having to go through the API layer and your api layer handles pushing the requests to the correct service methods and making sure that there is appropriate data available for them.
Don’t be passing the local scope around! There can be a shed load of stuff in there including all the other methods in the service. Just return what is required and nothing more.
There are other ways you can solve this that might be neater – for example you can actually put arguments into a method method call on a CFC from JSON. You could use cfajaxproxy to create the layer between your service and your javascript, enabling you to call your cfc methods directly as javascript functions. And I’m sure there are other solutions on top of these.
Remember…. ColdFusion == Serverside, Javascript == clientside. Separate them. Put a layer between them to handle communications.
Hope that helps.