JSON Parsing issue in Rails - ruby-on-rails

I am seeing a strange issue in Rails.
Request Body (request.body):
renewals[][driver_1][dl_number]=123&
renewals[][driver_1][expiration_date]=20130513&
renewals[][driver_1][last_name]=123&
renewals[][driver_1][state]=AL&
renewals[][driver_1][verified]=1&
renewals[][driver_2][verified]=0&
renewals[][id]=6415&
renewals[][insurance][expiration_date]=20130513&
renewals[][insurance][naic]=123&
renewals[][insurance][policy_number]=123&
renewals[][insurance][verified]=1&
renewals[][mailing_address][address_has_changed]=0&
renewals[][mailing_address][city]=GULF%20SHORES&
renewals[][mailing_address][state]=AL&
renewals[][mailing_address][street_address]=8094%20BEACH%20LANE&
renewals[][mailing_address][zip]=35023&
renewals[][driver_1][dl_number]=123&
renewals[][driver_1][last_name]=123&
renewals[][driver_1][state]=AL&
renewals[][driver_1][verified]=1&
renewals[][driver_2][verified]=0&
renewals[][id]=6412&
renewals[][insurance][expiration_date]=20130513&
renewals[][insurance][naic]=123&
renewals[][insurance][policy_number]=123&
renewals[][insurance][verified]=1&
renewals[][mailing_address][address_has_changed]=0&
renewals[][mailing_address][city]=HUEYTOWN&
renewals[][mailing_address][state]=AL&
renewals[][mailing_address][street_address]=123%20ANY%20LANE&
renewals[][mailing_address][zip]=35023&
renewals[][driver_1][dl_number]=123&
renewals[][driver_1][last_name]=123&
renewals[][driver_1][state]=AL&
renewals[][driver_1][verified]=1&
renewals[][driver_2][verified]=0&
renewals[][id]=6411&
renewals[][insurance][expiration_date]=20130513&
renewals[][insurance][naic]=123&
renewals[][insurance][policy_number]=123&
renewals[][insurance][verified]=1&
renewals[][mailing_address][address_has_changed]=0&
renewals[][mailing_address][city]=HUEYTOWN&
renewals[][mailing_address][state]=AL&
renewals[][mailing_address][street_address]=104%20MERRIMONT%20ROAD&
renewals[][mailing_address][zip]=35023&
JSON Parsed Params (params[:renewals]): https://gist.github.com/t2/5566652
Notice in the JSON that the driver_1 information is missing on the last record. Not sure why this is. The data is in the request. Any known bug I am missing? Let me know if you need more info.

Unfortunately this is just how Rails parses JSON like this (where your [] is massively nested). I've come up against this before - http://guides.rubyonrails.org/form_helpers.html#combining-them gave some explanation.
From what I remember, if you can put in numeric keys rather than just [] (i.e. [1] for the first one, [2] for the second etc.) then it will work as you want it to.

So I figured it out. I needed to set the requestSerializationMIMEType to RKMIMETypeJSON.

Related

#FirestoreQuery Not returning list of documents in Collection

I'm using FirebaseFirestoreSwift and Swift5.5 on iOS15+
I have this query:
#FirestoreQuery(
collectionPath: "/Users/" + Auth.auth().currentUser!.uid + "/Pages/"
) var pages2: [PageItem]
And I'm trying to get the following:
The structure is: /Users/{userId}/Pages/{pageId}/{key/value pairs}
I even confirmed from Firestore that the path was matching with its own.
This is from the console: /Users/JuzWOzAf54a7oFlOlb09dhAuOjI3/Pages/LZQAmbb18tYtz8ypkd8p
and this is what my string concatenation produces: /Users/JuzWOzAf54a7oFlOlb09dhAuOjI3/Pages/
So I should be getting the Page LZQAmbb18tYtz8ypkd8p and 3 others in the response, but thus far it is empty. Am I checking too early?
I am printing it like so:
.onAppear {
print(pages2)
}
On a view in the same file.
I don't even think it's a problem with printing it too soon, since it's meant to update in real-time.
But just incase it never showed since it was onAppear,and could have been received after, I added the following:
List {
ForEach(pages2) { page2 in
Text(page2.name)
}
}
And still, it receives nothing.
Not really sure what I'm doing wrong, I've researched and all I can find is a few resources, but they all seem to be doing the same thing, however, mine is simply not working, or I might be confused.
Any help is greatly appreciated, thank you!
Edit
This is the official SDK file whose methods I'm using:
https://github.com/firebase/firebase-ios-sdk/blob/master/Firestore%2FSwift%2FSource%2FPropertyWrapper%2FFirestoreQuery.swift
I am doing exactly as they propose.

iOS: Almofire PUT and DELETE Call is not working with Params in Swift

I am trying to Put and Delete data through Almofire Library but facing issue regarding parameters. Params are missing, following are the error:
Response JSON data = {
data = "<null>";
issuccess = 0;
msg = "{'car_id': [ErrorDetail(string='This field is required.', code='required')], 'car_brand_id': [ErrorDetail(string='This field is required.', code='required')], 'last_oil_change': [ErrorDetail(string='Date has wrong format. Use one of these formats instead: YYYY-MM-DD.', code='invalid')]} with error { Custom error message. }";
}
I am using the following code:
let params : [String : String] = ["brand_model_id": String(car_model_id), "oil_brand_id": String(oil_brand_id), "car_mileage": edCurrentMilage.text!, "car_modelyear": edVehicleModelYear.text!, "last_oil_change": edLastOilChange.text!]
Alamofire.request(Constants.APIURL + Constants.APIPOSTCARDATA ,method:.put, parameters: params, encoding: JSONEncoding.default, headers: header).responseJSON { [self] response in
guard response.result.isSuccess,
let value = response.result.value else {
print("Error while fetching tags: \(String(describing: response.result.error))")
self.hideIndicator()
// self.btn_submit_outlet.isEnabled = true
// completion(nil)
return
}
print(value)
let json = JSON.init(value as! NSDictionary)
print(json)
let code = json["issuccess"].boolValue
if(code)
{
self.hideIndicator()
Commons.showAlert(title: "Alert", error: "Data has been added.", VC: self)
}
else
{
self.hideIndicator()
Commons.showAlert(title: String.localizedStringWithFormat(NSLocalizedString("Alert", comment: "")), error: String.localizedStringWithFormat(NSLocalizedString("Something went wrong.", comment: "")), VC: self)
}
}
Above mention code is used for the PUT call Please help. Thanks in advance.
It's not against you particularly, BUT, it's something that is lacking a lot in this kind of questions.
Usually, by reading output error, in our case the server response we might, and I insist on "might", find the solution. But it's not always the case, sometimes error message is too generic, or pointing to the wrong direction. Here, error is saying about missing "car_id" param, but according to you it's not needed, so it's misleading (if we believe your saying).
Another usually good hint, is saying that "It's working on Android", "It's working in Postman", "It's working with a cURL command".
Usually, when this happen, I'm asking myself:
Why the author doesn't show the Postman, Android code, cURL command that would allow people knowing both tools/languages/platforms to spot a difference that could be the mistake.
Let's be honest, that would be easier, no? You might have quickly the right solution/fix, no? It's better than trying to guess battling agains the server response, no?
Now...
You are using Alamofire AND Postman. What if I told you that might be enough for you?
Quick trivia:
Did you know that Postman can generate code for the request?
It can even generate Swift Code for your request using URLSession? It's not "beautiful", "swifty" Swift code, but it's enough to spot difference and find why it's working on Postman and not in your code.
It can also generate cURL command? If you don't know about cURL a quick explanation would be "command line tool to make web request with params etc in Terminal.app/Bash/Shell, ie: it's basic and usually known by a lot of developers, so even if you only speak JavaScript, Java, etc, it's often like a "common language"
How? Even when I say that in comments, people don't even try to search for it... Let's find it with your favorite Search Engine, which should lead you to this tutorial/blog post. And tadaaa!
Did you know that AlamoFire can print request as cURL equivalent? It's stated here.
So in your case, what about asking Alamofire and Postman to generate cURL command and compare?
Then, you might want to change the parameters of the request, or even the parameters of the method request(_:method:parameters:encoding:headers:).
Why I am saying this?
Because if you don't give enough informations, there will be a delay between someone asking for more info/details in comment and yourself responding to them. Also, different commenters will ask for different questions, since debugging is a skill and causes might be multiples, we might ask different things, and only one will be relevant in the end to your issue, but we can't guess which one until then.
Because spotting difference is easier and might attract quicker response.
Now that you know about POSTMAN and Alamofire and cURL, you might even find yourself the solution. Even quicker than making a question on SO! Be your own hero!
In the end, only an "attractive" question will have good answers, so give as much info as possible, don't hold them (parameters sent, equivalent android code, screenshot at least of the Postman, but know that you know about the cURL generation code). Of course, keep your private token etc, obfuscate them a little, but still, you might have watch enough TV shows/movies where holding info is bad for the main characters, why repeating that mistake here?
As the error message says: Date has wrong format. Use one of these formats instead: YYYY-MM-DD.
Please check "last_oil_change" field. The value is from edLastOilChange.text. Does edLastOilChange.text meet the required format?

Array.size() returned wrong values (Grails)

I'm developing an app using Grails. I want to get length of array.
I got a wrong value. Here is my code,
def Medias = params.medias
println params.medias // I got [37, 40]
println params.medias.size() // I got 7 but it should be 2
What I did wrong ?
Thanks for help.
What is params.medias (where is it being set)?
If Grials is treating it as a string, then using size() will return the length of the string, rather than an array.
Does:
println params.medias.length
also return 7?
You can check what Grails thinks an object is by using the assert keyword.
If it is indeed a string, you can try the following code to convert it into an array:
def mediasArray = Eval.me(params.medias)
println mediasArray.size()
The downside of this is that Eval presents the possibility of unwanted code execution if the params.medias is provided by an end user, or can be maliciously modified outside of your compiled code.
A good snippet on the "evil (or lack thereof) of eval" is here if you're interested (not mine):
https://javascriptweblog.wordpress.com/2010/04/19/how-evil-is-eval/
I think 7 is result of length of the string : "[37,40]"
Seems your media variable is an array not a collection
Try : params.medias.length
Thanks to everyone. I've found my mistake
First of all, I sent an array from client and my params.medias returned null,so I converted it to string but it is a wrong way.
Finally, I sent and array from client as array and in the grails, I got a params by
params."medias[]"
List medias = params.list('medias')
Documentation: http://grails.github.io/grails-doc/latest/guide/single.html#typeConverters

HttpResponse truncating output

FileHelperEngine engine = new FileHelperEngine(typeof(OrderCsvRow));
var writer = new StreamWriter(Response.OutputStream);
engine.WriteStream(writer, someOrders);
When I output the orders as a string it comes out fine. when I use Response.OutputSteam as in the code snipped the response it truncated towards the end - always at the same place.
How do I fix this?
Fixed...
engine.WriteStream(Response.Output, someOrders);
Had a similar issue here, so I'll put down the solution I found for anyone else who comes by and needs it.
Source: https://bytes.com/topic/asp-net/answers/484628-response-outputstream-truncates-xmltextwriter
After doing your write, make sure you also flush your stream writer before completing the request. Otherwise the missing data might end up being left behind and not actually appended to the OutputStream. :)

Send params{} hash to another method in same controller

I am working on very complex and dynamic form where I do lot of calls to various methods to render partials depending upon values chosen for drop downs using jQuery. Problem is that after filling the form if it fails validation the form loses all the filled in values upon re-load. I got around this by sending some specific values from params{} hash to methods for my partials on re-load. But it is very cumbersome and I have large number of elements in params hash. How can send the whole params{} to another method in the same controller using jQuery?
Ok I tried this in my form:
$.post("/collections/show_selected_media_fields",{media_type: $("#collections_controller_ev0_media_id option:selected").text(), parent_form_action: "<%=params[:action]%>",ev0_manufacturer_id:"<%=params[:collections_controller_ev0].inspect%>", }, function(data) {$("#show_selected_media_fields").html(data);});
It produces following string sent as parameter:
Parameters: {"ev0_manufacturer_id"=>"{"client_asset_id"=>"", "status_id"=>"6", "server_
name"=>"", "media_id"=>"11", "serial_number"=>"", "evidence_number&quot
;=>"qwe", "notes"=>"", "model"=>"", "manufacturer_id"=>"69&quot
;, "interface"=>"SATA", "obtained_from"=>"wr", "evidence_type_id"=>"1"}
", "media_type"=>"Server", "parent_form_action"=>"quick_save"}
how can I convert this raw string to a hash in controller?
{"client_asset_id"=>
needs to be converted to
{"client_asset_id"=>"",... etc}
===========
ok I tried Tom's method. That produces the params as a string in the following shape. I tried to convert it into hash by doing an eval on it. But it errors out.
{commit=>Save, ev1_current_location_id=>, collections_controller_ev1=>{file_system=>NTFS, obtained_from=>, evidence_number=>, interface=>SAT
A, size_unit=>GB, manufacturer_id=>, encryption_version=>, media_id=>3, size=>, evidence_type_id=>3, other_encryption=>, encryption_method=>
N/A, serial_number=>, model=>, encryption_key=>}, ev0_from_location_category=>, ev0_obtained_from_email_id=>, collections_controller_ev0=>{o
btained_from=>, evidence_number=>, media_id=>1, evidence_type_id=>1, status_id=>6}, custody_action=>Create, collection=>{acquired_by=>Amande
ep Singh, custodian_id=>12, matter_id=>58, location=>sa Nose, client_id=>11, software_version=>, collection_date_time=>Fri Nov 30 14:28:06 -
0800 2012, acquisition_method=>Direct Collection, notes=>, software_id=>1}, _method=>put, utf8=>Γ£ô, ev1_current_location_category=>, ev0_cu
rrent_location_category=>, add_working_copy=>No, ev1_obtained_from_email_id=>, authenticity_token=>3vyn6057DDIyfgTnbckeh5heRTIgcVBfxtY89Krfr
/c=, ev1_existing_artifact_type=>, ev0_from_location_id=>, action=>quick_save, ev1_from_location_id=>, ev1_from_location_category=>, ev0_cur
rent_location_id=>, controller=>collections}
using .to_json and HTMLEntities gem I have gotten to a point where I have the following string. I need to convert it back to params hash. How to?
{"utf8"=>"Γ£ô","collection"=>{"acquired_by"=>"Amandeep Singh","notes"=>"","matter_id"=>"58","software_id"=>"1","acquisition_method"=>"Direct
Collection","client_id"=>"11","custodian_id"=>"0","collection_date_time"=>"Fri Nov 30 15=>52=>12 -0800 2012","software_version"=>"","locati
on"=>"sa Nose"},"ev0_current_location_id"=>"","ev1_existing_artifact_type"=>"","ev1_obtained_from_email_id"=>"","custody_action"=>"Create","
action"=>"quick_save","ev0_current_location_category"=>"","ev1_from_location_category"=>"","_method"=>"put","ev0_obtained_from_email_id"=>""
,"ev0_from_location_category"=>"","ev1_current_location_category"=>"","commit"=>"Save","controller"=>"collections","authenticity_token"=>"3v
yn6057DDIyfgTnbckeh5heRTIgcVBfxtY89Krfr/c=","ev0_from_location_id"=>"","ev1_current_location_id"=>"","collections_controller_ev0"=>{"status_
id"=>"6","media_id"=>"9","obtained_from"=>"","evidence_number"=>"","evidence_type_id"=>"1"},"collections_controller_ev1"=>{"media_id"=>"3","
encryption_key"=>"","encryption_version"=>"","size"=>"","obtained_from"=>"","encryption_method"=>"N/A","model"=>"","evidence_number"=>"","ev
idence_type_id"=>"3","size_unit"=>"GB","other_encryption"=>"","interface"=>"SATA","file_system"=>"NTFS","serial_number"=>"","manufacturer_id
"=>""},"ev1_from_location_id"=>"","add_working_copy"=>"No"}
========== edit==========
I am using the following in my view.
JSON( params[:collections_controller_ev0])
It sends following quoted string to my controller.
{"evidence_number":"","notes":"","size":"","model":"","evidence_type_id":"1","media_id":"1","obtained_from":"","status_id":"6","manufacturer_id":"","size_unit":"GB"}
I convert it into valid JSON string as below using gsub('"','"'). The output is a VALID JSON string as validated by http://jsonlint.com/ shown below.
{"evidence_number":"","notes":"123","size":"123","model":"123","evidence_type_id":"1","media_id":"1","obtained_from":"","status_id":"6","manufacturer_id":"69","size_unit":"GB"}
JSON.parse works without error on this string but does not produce a properly formed hash. It produces following:
notes123evidence_numbersize123model123evidence_type_id1media_id1obtained_fromstatus_id6size_unitGBmanufacturer_id69
Can someone please tell me how to correct this?
Try <%=raw params[:action]%> and <%=raw params[:collections_controller_ev0]%> instead
I think it will work fine.
$.post("/collections/show_selected_media_fields",{media_type: $("#collections_controller_ev0_media_id option:selected").text(), parent_form_action: <%=raw params[:action]%>,ev0_manufacturer_id:<%=raw params[:collections_controller_ev0].inspect%>, }, function(data) {$("#show_selected_media_fields").html(data);});
params is basically a hash. So you can use .to_json on it. Then in your controller you can convert it from JSON to a hash with JSON.parse().
It's generally a much better idea to use JSON if you're going to be dealing with it in Javascript or HTML at all.
The method showed in my last edit works! it produces correct hash.

Resources