Ignoring => when converting hash in ruby? How to properly convert hash? - json

I'm sending a post request, and this is the payload:
data = {updates: [{action: "create", user_id: "2", type: "view"}]}
but when I send it, the API says it was expecting:
{ action: \"create\", user_id: \"id\", type: \"type\" }
but it getting:
{:action=\u003e\\\"create\\\", :user_id=\u003e2\\\"2\\\", :type=\u003e\\\"view\\\"}\
The => is getting converted. I tried using to_json but that didn't help me.
How do I convert this properly? I think it has something to do with the nested array/hash because all the others work fine.
Also, I'm setting my request body and sending like so:
request.set_form_data(body)
https.request(request)
Looks like I need to use this syntax in order to pass set_form_data a nested hash:
{'a[b]': 'c'} is the same as {'a' => {'b' => 'c'}}
but is there a way to include the array? I need to have:
data = {updates: [{action: "create", user_id: "2", type: "view"}]}
in this notation.

As you mentioned, set_form_data does not accept arrays. It looks like a workaround if you wanted to continue using the Net::HTTP library is to encode the data and pass it to request.body.
request.body = "updates[][action]=create&updates[][type]=view&updates[][user_id]=2"
request.content_type = 'application/x-www-form-urlencoded'
You could also create a custom function like they did in this post: http://cloudlines.tumblr.com/post/653645115/postput-arrays-with-ruby-nethttp-setformdata
Check out this post on changing complex objects into a querystring: https://coderwall.com/p/uh8kiw/pass-arrays-objects-via-querystring-the-rack-rails-way.
Hope that helps!

Related

creating AWS resource group using boto3

I would like to create AWS resource group using boto3. In the resource group I would like to add ec2 instances having tags "name":"Jenkins".Below is the syntax suggested in boto3 documentation.
response = client.create_group(
Name='string',
Description='string',
ResourceQuery={
'Type': 'TAG_FILTERS_1_0'|'CLOUDFORMATION_STACK_1_0',
'Query': 'string'
},
Tags={
'string': 'string'
}
)
I read the documentation but I did not understand what query is in my case and couldn't find any example of creating resource groups using boto3 online. In the ResourceQuery dictionary, I can use 'Type' as 'TAG_FILTERS_1_0' but not sure what 'Query' would be. It would be great if I can get an example explanation of creating a resource group. Thank you
Update
After following #Jarmod suggestion, I tried the following code
client = boto3.client('resource-groups', **conn_args)
response = client.create_group(
Name='JenkinsResource',
Description='JenkinsResourceGrp',
ResourceQuery={
'Type': 'TAG_FILTERS_1_0',
'Query': [{"Key": "name", "Values": "Jenkins"}]
}
)
I ended up with the following error.
Invalid type for parameter ResourceQuery.Query, value: [{'Key': 'name', 'Values': 'Jenkins'}], type: , valid types:
I was able to get it to work with the Query object being:
{
'ResourceTypeFilters': ['AWS::AllSupported'],
'TagFilters': [{
'Values': ['Jenkins'],
'Key': 'name'
}]
}
And then as it's expecting a string and not a json object I did a json.dumps(query).
I discovered this by generating it through the web console and then having a look at the CloudTrail logs to see what the console did :)

Get JSON in POST in kemal

What I want is a POST request in kemal where the body has a certain number of keys/values that I want to access and then an arbitrary JSON Object that I just want to stringify and pass on and later parse back to JSON.
My problem is that I apparently can't get the types right.
Think of a potential JSON body like this:
{
"endpoint": "http://example.com",
"interval": 500,
"payload": {
"something": "else",
"more": {
"embedded": 1
}
}
}
Now what I've been trying to do is the following:
require "kemal"
post "/schedule" do |env|
endpoint = env.params.json["endpoint"].as(String)
interval = env.params.json["interval"].as(Int64)
payload = String.from_json(env.params.json["payload"].as(JSON::Any))
# ... move things along
env.response.content_type = "application/json"
{ id: id }.to_json
end
Kemal.run
Now apparently what I seem to be getting when accessing "payload" is something of type Hash(String, JSON::Type), which confuses me a bit.
Any ideas how I'd be able to just get a sub-JSON from the request body, transform it to String and back to JSON?
Updated: payload is a type of JSON::Type. Casting and then calling .to_json does the trick.
require "kemal"
post "/schedule" do |env|
endpoint = env.params.json["endpoint"].as(String)
interval = env.params.json["interval"].as(Int64)
payload = env.params.json["payload"].as(JSON::Type)
env.response.content_type = "application/json"
payload.to_json
end
Kemal.run

how to serialize parameters using axios

How would I serialize url parameters for use with axios? My parameters are just numbers in array [1,2]. Here is my code so far
axios({
method: 'delete',
url: '/api/'
})
My request url will be something like this http://127.0.0.1:8000/api/?id=1&id=2
I looked at the paramsSerializermethod that axios has but its confusing how it can be used or whether its even appropriate in my case. Please advice. Thanks
the config object of axios.get accepts params. In params you can specify your array and it will do the conversion for you.
Here is an example:
axios.get('/api/', {
params: {
id: [1,2]
}
})
This will make a request which looks like this:
/api/?id[]=1&id[]=2

$http.get messing JSON parameters

I'm comunicating my Rails API with my AngularJS application.
Everything is working great and normal up until the point I have to send parameters in a GET request. This is the Rails controller
def cats
if cat_params[:color]
#cats = Cat.where(... #you know
else
//Do something else
end
private
def cat_params
params.require(:cat).permit(:color)
end
Then from Angular
var kitty = {
cat: {
color: "red"
}
}
$http.get('some URL', { params: kitty }).success.....
By this time, the params hash looks like a stringify JSON
Started GET "some URL?cat=%7B%22color%22:%22red%22%7D" for 127.0.0.1 at 2015-01-28 23:10:24 -0300
Processing by Some_controller as JSON
Parameters: {"cat"=>"{\"color\":\"red\"}", "cat_id"=>"19"}
Cat Load (0.5ms) SELECT "cat".* FROM "cats" WHERE "cat"."id" = 19 LIMIT 1
{"cat"=>"{\"color\":\"red\"}", "format"=>"json", "controller"=>"some_controller", "action"=>"some_action", "cat_id"=>"19"}
Completed 500 Internal Server Error in 95ms
NoMethodError - undefined method `permit' for "{\"cat\":\"red\"}":String:
I'm also sending the Content-Type header, set to 'application/json'.
From Angular's $http.get documentation, I read that if the value of params is something other than a string, it will stringify the JSON object, so the issue is not in the front-end.
I don't think the solution begins with starting JSON parsing the params hash, since I've had no need to do it in the past. It seems to me that strong_parameters is playing dirty, or Rails is ignoring the JSON string. Any ideas what to do next?
I just ran into the same issue. Changing the param serializer solved the issue for me:
$http.get('someURL', {
paramSerializer: '$httpParamSerializerJQLike',
params: {cat: {color: 'red}}
})
Also adding the 'Content-Type': 'application/json' header will not help since it applies to the the body the request.
I used to meet a $http.get problem that when call $http.get('some url', {params:SOME_PARAMS}), SOME_PARAMS could be transformd to key-value params when it is a simple key-value data like {color:'red'}, and it would transform params to json string when it is a complex type like {cat:{color:'red'}}.
So to solve your question, I suggest that add params behind url like:
$http.get('some URL?cat[color]=red').success.....

Is it possible to send an array with the Postman Chrome extension?

I've been using Postman Chrome extension to test out my API and would like to send an array of IDs via post. Is there a way to send something list this as a parameter in Postman?
{
user_ids: ["1234", "5678"]
}
You need to suffix your variable name with [] like this:
If that doesn't work, try not putting indexes in brackets:
my_array[] value1
my_array[] value2
Note:
If you are using the postman packaged app, you can send an array by selecting raw / json (instead of form-data). Also, make sure to set Content-Type as application/json in Headers tab.
Here is example for raw data {"user_ids": ["123" "233"]}, don't forget the quotes!
If you are using the postman REST client you have to use the method I described above because passing data as raw (json) won't work. There is a bug in the postman REST client (At least I get the bug when I use 0.8.4.6).
For me did not work with array[0], array1, .. or array[], array[], ... .
It works more simply:
If you want an array of dicts, try this:
Here is my solution:
use form-data and edit as below:
Key Value
box[] a
box[n1] b
box[n2][] c
box[n2][] d
and you will get an array like this:
{"box":{"0":"a","n1":"b","n2":["c","d"]}}
It is important to know, that the VALUE box is only allowed to contain a numeral value (no specifiers).
If you want to send e.g. an array of "messages" with Postman, each having a list of key/value pairs, enter e.g. messages[][reason] into the KEY box and the value of reason into the VALUE box:
The server will receive:
{"messages"=>[{"reason"=>"scrolled", "tabid"=>"2"}, {"reason"=>"reload", "tabid"=>"1"}], "endpoint"=>{}}
I also had that problem, and solved it by doing the following:
1 - Going to the request header configuration and added the following:
Accept : application/json, text/plain, */*
Content-Type : application/json;charset=UTF-8
2 - To send the json array, I went to raw json format and set the user_ids to array:
user_ids: ["bbbbbbbbbb","aaaaaaaaaa","987654321","123456789"]
Set Body as raw and form the array as follows:
As mentioned by #pinouchon you can pass it with the help of array index
my_array[0] value
my_array[1] value
In addition to this, to pass list of hashes, you can follow something like:
my_array[0][key1] value1
my_array[0][key2] value2
Example:
To pass param1=[{name:test_name, value:test_value}, {...}]
param1[0][name] test_name
param1[0][value] test_value
Go to Header and select Content-Type = application/json then go to body and select raw and then pass an array.
this worked for me. to pass an array of Item object {ItemID,ColorID,SizeID,Quntity}
in headers set
content-type : application/x-www-form-urlencoded
In body select option
x-www-form-urlencoded
and insert data as json array
user_ids : ["1234", "5678"]
This also works for lists within the object:
Id:37
IdParent:26
Name:Poplet
Values[0].Id:1349
Values[0].Name:SomeName
Values[1].Id:1350
Values[1].Name:AnotherName
the equivalent JSON would be:
{
"Id": 37,
"IdParent": 26,
"Name": "Poplet",
"Values": [
{
"Id": 1349,
"Name": "SomeName"
},
{
"Id": 1350,
"Name": "AnotherName"
}
]
}
{
"data" : [
{
"key1" : "value1",
"key2" : "value2"
},
{
"key01" : "value01",
"key02" : "value02"
},
{
"key10" : "value10",
"key20" : "value20"
}
]
}
You can pass like this.
In form-data you can pass a array like this
and in backend you will fetch it like a
"tags"=>["aaaa", "bbb"]
In my case I've to pass two values in a array so I write it two times
Choose either form-data or urlencoded and use the same key "user_ids". The server should receive it as an array.
In form-data,
key value
user_ids[] 1234
user_ids[] 5678
My back-end is written in Ruby on Rails. This is how I sent the array params using Postman. It worked for me.
UPDATE
I'm using x-www-form-urlencoded. I believe it will work too for form-data.
To send an array using form data there's no need to use brackets.
Just send that specific array using the same name in multiple fields.
Like:
my_array:value_1
my_array:value_2
Although this question has already accepted a solution still that solution has a drawback that is we have to repeat the key (Array name) again and again as one key is accepting only one value. Like this:
Imagine we have 10 values or more, should we repeat the same Array name each time? The programmatic answer is NO. Then we should do the following that is a better approach.
Select the form-data as usual
Type Array name in the Key field
Pass the Array in Value field
Like this:
Now, you should be able to send the Array, but wait, this won't be stored in Database like that in my case with MongoDB. So what you have to do is, use the following piece of code to send it like an Array in the Database:
First, we need to parse it using JSON, like this
let user_ids = JSON.parse(body.user_ids);
Now, you can send user_ids variable to database like an Array
That's All!
I tried all solution here and in other posts, but nothing helped.
The only answer helped me:
Adding [FromBody] attribute before decleration of parameter in function signature:
[Route("MyFunc")]
public string MyFunc([FromBody] string[] obj)
Supposing you have the array of object below,
features: [
{
title: { type: String },
type: { type: String },
},
],
To add the values on the form data on the postman, add it this way
features[title]
features[type]
Check also the image below
Here is something that worked for me
{
"user_ids":["[1234, 5678]"]
}
I believe it depends on how the backend is setup most of the time.
N.B Now we are in 2022 if All of the above solutions didn't, just don't panic. pass array name with is value without a bracket and the add it multiple time, just link how the image below is showing. it should work just fine. If It does work, buy me some coffee, hhh
In my case I need to send array of objects, I sent it like this
Request header configuration and added the following
Accept: application/json
You need to suffix your key variable name with []
like key[0][name]
You can insert it in "bulk-edit" mode
Body section in form-data on right side click Bulk Edit and added the following
items[0][prod_id]:174336
items[0][item_weight]:3.400
items[0][item_qty]:1
items[0][item_selected_melting]:92
items[0][item_remarks]:
items[1][prod_id]:12345