I'm doing an external API query ussing HTTParty, the resultant of that query is a hash that gets stored in an instance variable in my controller. Without saving it to my database I need to access the contents of the hash to send it as a string to another external app.
Here is my controller HTTParty call
#api_response = HTTParty.get("http://xxxxxxxxx.xx/vehicle/reg/#{#user.reg_number}/xxxxxxxxxxxxxxxxxxxxx")
Here is the response I get that is stored in #api_response:
{"response"=>
{"basic"=>
{"reg"=>"xxx", "make"=>"xxxx", "model"=>"xxxx", "version"=>"xxxxx", "body"=>"xxxxxx", "doors"=>"x", "reg_date"=>"xxxxxx", "engine_cc"=>"xxxxxx", "colour"=>"xxxxx", "fuel"=>"xxxxxx", "transmission"=>"x", "data_type"=>"x", "co2_emissions"=>"xxx"}
}
}
As it is I'm able to display the contents of #api_response in my views, but I need to retrieve the info and pass it on.
You access values in a hash using square brackets surrounding the hash key. For example, to access reg out of that response, you would do:
#api_response["response"]["basic"]["reg"]
Is that all you're looking for, or did you need to do something else with it?
Related
I have the following code:
dim key
for each key in Request.Querystring
'do something
key = sanitized_param(key)
next
My question for you classic-asp connoisseur, does classic-asp, or asp in general, pass the variables as references(memory), or by value? Trying to figure out if I sanitize the key variable and pass it back to itself, is it just "alive" for that loop, or does the new value get passed to the original QueryString?
Request.QueryString retrieves the query string parameters by value from the page headers.
You can only make changes to a query string once its been retrieved via Request.QueryString, but you can't make changes directly to Request.QueryString as it's read-only (If you could make changes you would presumably use Response.QueryString, but this isn't a valid response command).
I'm guessing you're trying to sanitize all your query strings in one go? This isn't really possible or indeed necessary. You would typically sanitize a query string as and when you request it:
Response.Write(sanitized_param(Request.QueryString("myQS")))
Or to assign the query string to a variable first then sanitize it:
Dim myQS
myQS = Request.QueryString("myQS")
myQS = sanitized_param(myQS)
' or
myQS = sanitized_param(Request.QueryString("myQS"))
Once the query string has been assigned to a variable and sanitized you're able to reference that variable as often as you like without having to pass it to your sanitize function again.
Also, your example code doesn't make much sense. The key value in your for each loop is referencing just the names of your query strings and not their values. If Response.QueryString was a valid ASP command you would do:
Response.QueryString(key) = sanitized_param(Request.QueryString(key))
But again, this isn't possible.
EDIT: This solution might be what you're looking for:
Create a dictionary object, call it "QueryString" for example. Loop through all your query strings and add a sanitized version to the dictionary object.
Dim QueryString : Set QueryString = Server.CreateObject("Scripting.Dictionary")
For Each Item In Request.QueryString
QueryString.Add Item,sanitized_param(Request.QueryString(Item))
next
Now, to retrieve a sanitized version of a query string just use:
QueryString.Item("query_string_name")
Or for the original unsanitized version you could still use:
Request.QueryString("query_string_name")
Just like Request.QueryString, the dictionary object is forgiving and won't return an error if you ask for a query string that doesn't exist.
You could also create a function for retrieving sanitized query strings, for example:
Function SanitizedQS(ByVal qsName)
SanitizedQS = sanitized_param(Request.QueryString(qsName))
End Function
And rather than using Request.QueryString("query_string_name") just use SanitizedQS("query_string_name").
I would like to make an API call dynamically. API (Get) result must vary dynamically based on the query string passed.
I have hard coded the API URL without any query string, and supplied the API URL as an instance variable:
#apiRequest = HTTParty.get("http://localhost:1880/api/devices")
#parseApiRequest = JSON.parse(#apiRequest.body)
I want #apiRequest to change dynamically based on user input from a form (I had already developed a form that gets inputs from user's).
Is it possible to change the value of an instance variable dynamically? User's input value must be passed onto that controller as a query string.
Sample image that gets user input:
Getting User Input
The instance variable must be updated dynamically as,
#apiRequest = HTTParty.get("http://localhost:1880/api/devices?device_id=123456")
Kindly suggest.
Simply interpolate the dynamic data into the api request parameter string:
extraParamsOrPath = "assemble this from form inputs"
urlPrefix = "http://localhost:1880/"
#apiRequest = HTTParty.get("#{urlPrefix}/#{extraParamsOrPath}")
And make sure the user input is sanitized ;)
I am calling an API that returns an array of JSON objects and I can access return values of the API call
[{"param1":1,"param2":"blah1"},
{"param1":2,"param2":"blah2"},
{"param1":3,"param2":"blah3"}]
I know that i can access each Param1 through iteration or by static indexing like #client[0].param1 #client[1].param1 #client[2].param1 but the thing is , i don't want param2 and i want just param1 . is there any way , to access param1 without iteration or static indexing
so that i could get the below result in response
[{"param1":1},
{"param1":2},
{"param1":3}]
Update
The thing to notice is that i want to filter the result while making
the request (before getting the response when we know the attribute
name)
Try to use delete.
Deletes and returns a key-value pair from hsh whose key is equal to
key. If the key is not found, returns the default value. If the
optional code block is given and the key is not found, pass in the key
and return the result of block.
data = [{"param1":1,"param2":"blah1"},
{"param1":2,"param2":"blah2"},
{"param1":3,"param2":"blah3"}]
data.each {|x| x.delete("param2")}
For more information about delete.
I hope this help you.
I have some data that I need to persist through multiple actions within my Grails app. Due to the nature of the data, I would prefer not to store the data in the session. Here is an example of what I would like to do.
class MyController{
def index(){
MyObject object = MyObject.new(params.first, params.second, params.third)
[gspObject:object]
}
def process(){
MyObject object = params.gspObject
//continue from here
}
}
In my GSP if I do
<g:form action="process" params="[gspObject:gspObject]">
Then I get the error
Cannot cast object 'net.package.MyObject#699c14d8' with class 'java.lang.String' to class 'net.package.MyObject'
My question is, If I want to get the object back that I sent to the gsp, how can I get that? Is there some kind of scope that I can save the object in that would be a little safer then session? Is there a way to pass the object into the page itself and pass it back in the next request?
Grails has many layers, but at the bottom you have plain old HTTP just like in any web app. It's a stateless protocol, and you send a text or binary response, and receive text or text + binary requests. But you can't expect to be able to send an arbitrary object to a web browser in HTML and receive it back again in the same state as when you sent it - where is this Java/Groovy JVM object going to be stored in the browser?
You have basically two options. One is to store it at the server, which is less work because it remains as the same object the whole time. The session is a good location because it's coupled to the user, is created on-demand and can automatically time out and be removed, etc. The other is to do what you're trying to do - send it to the client and receive it back - but you are going to have to serialize it from an object (which could be a complex object containing arbitrarily many other objects) and deserialize it from the format you used on the client back into Java/Groovy objects.
JSON is a good option for serialization/marshalling. You could store the stringified object in a hidden form element if your page uses a form, or in a querystring arg if you click a link from this page to the next in the workflow. Don't send all of the object's data though, only what you need to rebuild it. Anything that's available in the database should be referenced by id and reloaded.
Something like
[gspObject: object as JSON]
or
[gspObject: [first: object.first, first: object.firstsecond, ...] as JSON]
will get it in the correct format for sending, and then you can parse the JSON from the request to reinstantiate the instance.
According to the document on command objects and data binding. Once you read the params object, that object can never be reused again.
From the documentation:
Binding The Request Body To Command Objects
http://grails.org/doc/2.3.x/guide/theWebLayer.html#commandObjects
Note that the body of the request is being parsed to make that work. Any attempt to read the body of the request after that will fail since the corresponding input stream will be empty. The controller action can either use a command object or it can parse the body of the request on its own (either directly, or by referring to something like request.JSON), but cannot do both.
I'm trying to view the parameters within a filter (which is hit before the controller is requested). Would logging the parameters to a log cause the controller to get a null param object? From the documentation that looks to be the case. However, how can I get access to the params without wiping them out in the filter?
Once you read the params object, that object can never be reused
again.
That is not correct. You can read request parameters over and over again. What cannot be read over and over again is the body of the request. The body and the request parameters are 2 different things.