Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Submitting JSON as body? #36

Closed
justindunn opened this issue May 19, 2017 · 6 comments
Closed

Submitting JSON as body? #36

justindunn opened this issue May 19, 2017 · 6 comments

Comments

@justindunn
Copy link

justindunn commented May 19, 2017

I'm trying to submit a JSON post to my local dev server and having issues. I haven't seen much documentation on sending complex parameters or JSON in the body for a POST request in the documentation (unless I'm missing something). I've been browsing through issues with no success unfortunately on how to get this to work, I have a complex bit of JSON that I need to send in a .POST request to my Rails API. Here is the code for sending the JSON

 `@IBAction func SessionSubmit(_ sender: Any) {
    let selected_session_type = session_type_ids[self.SessionTypePicker.selectedRow(inComponent: 0)]
    let selected_session_duration = session_type_durations[self.SessionTypePicker.selectedRow(inComponent: 0)]
    let dateFormatter = DateFormatter()
    let selected_start_time = DateTimePicker.date
    let start_time = dateFormatter.string(from: DateTimePicker.date)
    let end_time = dateFormatter.string(from: selected_start_time + selected_session_duration.minutes)
    let refreshToken = current_user.refreshToken as String
    let accessToken = current_user.accessToken as String
    let params: [String: Any] = ["access_token": accessToken, "refresh_token": refreshToken]
    let body: [String: Any] = ["data": [
                    "type": "session",
                    "attributes": [
                        "title": "",
                        "description": "",
                        "start": start_time,
                        "end": end_time,
                        "session_mode": "video_session"],
                        "relationships": [
                            "users": [
                                "data": [
                                    ["type": "user",
                                     "id": current_user.userId],
                                    ["type": "user",
                                     "id": clientId]
                                ]
                            ],
                            "session_type":[
                                "data": [
                                    "type": "session_type",
                                    "id": selected_session_type
                                    ]
                                ]
                            ]
                        ]
                    ]
    do {
        let jsonData = try JSONSerialization.data(withJSONObject: body, options: .prettyPrinted)
        print(jsonData)
        let decoded = try JSONSerialization.jsonObject(with: jsonData, options: [])
        print(decoded)
        
        if let dictFromJSON = decoded as? [String:Any] {
            print(dictFromJSON)
            self.sendData(parameters: params, body: dictFromJSON) {
                self.stopAnimating()
            }
        }
    } catch {
        print(error.localizedDescription)
    }
    startAnimating(GlobalVariables().LoadingSize)`

   `    func sendData(parameters: [String:Any], body: [String:Any], finished: @escaping () -> Void) {
    DataController().Post(parameters: parameters, path: "/v1/sessions/"+current_user.userId).perform(withSuccess: { (FetchedArray) in
        if let SessionTypesArray = FetchedArray.response["data"].array {
            self.session_types += SessionTypesArray 
        }
        finished()
    }) { (FetchFailed) in
        AuthenticationController().logout(user: self.current_user)
        self.dismiss(animated: true, completion: {});
        finished()
    }
}`

I'm thinking maybe I need to make these embedded in the document and only have my refresh and access tokens as parameters? so I tried working on doing it that way and yet still another road block because of not seeing any ways to add to the body, I know there is appendBody but I'm not sure how that would work either, the json seems to not be flowing to the rails api correctly either
`Started POST "/v1/sessions/122" for 127.0.0.1 at 2017-05-19 13:52:32 -0400
Error occurred while parsing request parameters.
Contents:

access_token=90d2befd58912f978dc681f2f0d1eaf3d217dbe25fdac3d1ec4ab45e9bfff41a&data%5Btype%5D=session&data%5Battributes%5D%5Bdescription%5D=&data%5Battributes%5D%5Btitle%5D=&data%5Battributes%5D%5Bend%5D=&data%5Battributes%5D%5Bsession_mode%5D=video_session&data%5Battributes%5D%5Bstart%5D=&data%5Brelationships%5D%5Bsession_type%5D%5Bdata%5D%5Btype%5D=session_type&data%5Brelationships%5D%5Bsession_type%5D%5Bdata%5D%5Bid%5D=379&data%5Brelationships%5D%5Busers%5D%5Bdata%5D%5B%5D%5Btype%5D=user&data%5Brelationships%5D%5Busers%5D%5Bdata%5D%5B%5D%5Bid%5D=122&data%5Brelationships%5D%5Busers%5D%5Bdata%5D%5B%5D%5Btype%5D=user&data%5Brelationships%5D%5Busers%5D%5Bdata%5D%5B%5D%5Bid%5D=6&refresh_token=6b60a52534e1fa2ed436a9542a6c27b7f05e56e7b306f48df12b286b8fe5f624

JSON::ParserError - 822: unexpected token at 'access_token=90d2befd58912f978dc681f2f0d1eaf3d217dbe25fdac3d1ec4ab45e9bfff41a&data%5Btype%5D=session&data%5Battributes%5D%5Bdescription%5D=&data%5Battributes%5D%5Btitle%5D=&data%5Battributes%5D%5Bend%5D=&data%5Battributes%5D%5Bsession_mode%5D=video_session&data%5Battributes%5D%5Bstart%5D=&data%5Brelationships%5D%5Bsession_type%5D%5Bdata%5D%5Btype%5D=session_type&data%5Brelationships%5D%5Bsession_type%5D%5Bdata%5D%5Bid%5D=379&data%5Brelationships%5D%5Busers%5D%5Bdata%5D%5B%5D%5Btype%5D=user&data%5Brelationships%5D%5Busers%5D%5Bdata%5D%5B%5D%5Bid%5D=122&data%5Brelationships%5D%5Busers%5D%5Bdata%5D%5B%5D%5Btype%5D=user&data%5Brelationships%5D%5Busers%5D%5Bdata%5D%5B%5D%5Bid%5D=6&refresh_token=6b60a52534e1fa2ed436a9542a6c27b7f05e56e7b306f48df12b286b8fe5f624':
json (1.8.6) lib/json/common.rb:155:in parse'

any help here would be greatly appreciated guys! thanks in advance!

@DenTelezhkin
Copy link
Member

Just do:

request.parameters = body
request.parameterEncoding = JSONEncoding.default

You don't need to explicitly create JSON using JSONSerialization, since it's already implemented in Alamofire ParameterEncoding, and therefore, in TRON as well.

@justindunn
Copy link
Author

justindunn commented May 21, 2017

Ok I tried adding that to my api controller for the request, but instead of using body I just went back and added everything to my main params
let params: [String: Any] = ["access_token": accessToken, "refresh_token": refreshToken, "data": [ "type": "session", "attributes": [ "title": "", "description": "", "start": start_time, "end": end_time, "session_mode": "video_session"], "relationships": [ "users": [ "data": [ ["type": "user", "id": current_user.userId], ["type": "user", "id": clientId] ] ], "session_type":[ "data": [ "type": "session_type", "id": selected_session_type ] ] ] ] ]

my api controller code is this
func PostCreate(parameters: [String:Any], path: String) -> APIRequest<Fetched, FetchFailed> { let request: APIRequest<Fetched, FetchFailed> = DataController.tron.request(path) request.method = .post request.parameterEncoding = JSONEncoding.default request.headers = ["Accept":"application/vnd.api+json"] request.headers = ["Content-Type":"application/vnd.api+json"] print(request.path) print(request.parameters) print(request.headers) print(request.urlBuilder) return request }

But now I'm getting an invalid media type, I'm thinking that JSONEncoding.default is messing up the ""application/vnd.api+json" content-type, right?

@DenTelezhkin
Copy link
Member

It should not reset Content-Type, if you set it before sending a request

https://github.com/Alamofire/Alamofire/blob/master/Source/ParameterEncoding.swift#L313-L314

@justindunn
Copy link
Author

func PostCreate(parameters: [String:Any], path: String) -> APIRequest<Fetched, FetchFailed> {
    let request: APIRequest<Fetched, FetchFailed> = DataController.tron.request(path)
    request.method = .post
    request.parameterEncoding = JSONEncoding.default
    request.headers = ["Accept":"application/vnd.api+json"]
    request.headers = ["Content-Type":"application/vnd.api+json"]
    print(request.path)
    print(request.parameters)
    print(request.headers)
    print(request.urlBuilder)
    return request
}

when I submit it with that I get

"errors" : [
{
"code" : "406",
"status" : "406",
"title" : "Not acceptable",
"detail" : "All requests must use the 'application/vnd.api+json' Accept without media type parameters. This request specified 'application/json'."
}
]

but if I comment out the JSONEncoding.default I get the issue I had originally

Started POST "/v1/sessions/" for 127.0.0.1 at 2017-05-21 11:37:17 -0400
Error occurred while parsing request parameters.
Contents:

access_token=9856a83b1a286343482a729e5ec7c909f838e43fc0623586e38c13ff0bb72c10&data%5Btype%5D=session&data%5Battributes%5D%5Bdescription%5D=&data%5Battributes%5D%5Btitle%5D=&data%5Battributes%5D%5Bend%5D=&data%5Battributes%5D%5Bstart%5D=&data%5Battributes%5D%5Bsession_mode%5D=video_session&data%5Brelationships%5D%5Busers%5D%5Bdata%5D%5B%5D%5Btype%5D=user&data%5Brelationships%5D%5Busers%5D%5Bdata%5D%5B%5D%5Bid%5D=122&data%5Brelationships%5D%5Busers%5D%5Bdata%5D%5B%5D%5Btype%5D=user&data%5Brelationships%5D%5Busers%5D%5Bdata%5D%5B%5D%5Bid%5D=6&data%5Brelationships%5D%5Bsession_type%5D%5Bdata%5D%5Btype%5D=session_type&data%5Brelationships%5D%5Bsession_type%5D%5Bdata%5D%5Bid%5D=679&refresh_token=6b368c95d13e7ecece91dfe1ade30e80ccb7d7311ffcf0771086f227e1de72fc

JSON::ParserError - 822: unexpected token at 'access_token=9856a83b1a286343482a729e5ec7c909f838e43fc0623586e38c13ff0bb72c10&data%5Btype%5D=session&data%5Battributes%5D%5Bdescription%5D=&data%5Battributes%5D%5Btitle%5D=&data%5Battributes%5D%5Bend%5D=&data%5Battributes%5D%5Bstart%5D=&data%5Battributes%5D%5Bsession_mode%5D=video_session&data%5Brelationships%5D%5Busers%5D%5Bdata%5D%5B%5D%5Btype%5D=user&data%5Brelationships%5D%5Busers%5D%5Bdata%5D%5B%5D%5Bid%5D=122&data%5Brelationships%5D%5Busers%5D%5Bdata%5D%5B%5D%5Btype%5D=user&data%5Brelationships%5D%5Busers%5D%5Bdata%5D%5B%5D%5Bid%5D=6&data%5Brelationships%5D%5Bsession_type%5D%5Bdata%5D%5Btype%5D=session_type&data%5Brelationships%5D%5Bsession_type%5D%5Bdata%5D%5Bid%5D=679&refresh_token=6b368c95d13e7ecece91dfe1ade30e80ccb7d7311ffcf0771086f227e1de72fc':

Another catch 22 unfortunately, does this seem like its something wrong with our backend api?

@DenTelezhkin
Copy link
Member

You should append, but not reassign headers

request.headers["Accept"] = "application/vnd.api+json"
request.headers["Content-Type"] = application/vnd.api+json"

@justindunn
Copy link
Author

Awesome, I think that got it, now I'm having an authentication issue with our server, but I don't think it has anything to do with what we were trying to solve, thanks again for all your help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants