Search code examples
rubyjsonsinatraopalrbreact.rb

opal-jquery ajax request sending malformed json string


I'm using opal-jquery to send an ajax request to my backend, but the json payload is malformed when I try to access it on the backend.

When I do puts @params.to_s on my back end, it gets displays as:

{"{\"username\":\"some_user\", \"password\":\"some_password\"}"=>nil}

So to get the login details I have to do:

@params.each do |k,v|
    login_details = JSON.parse(k)
end

My front end (opal) submit request looks like this:

    def handle_login_submit details
    url = "/client/api/auth"
    HTTP.post url, payload: details.to_json, dataType: 'json' do |response|
        case response.status_code / 100
        when 2
            puts response.status_code
            self.login_state = :return_success 
            puts response.json
        when 4
            self.login_state = :return_failed
            puts response.status_code
            puts response.json
        when 5
            self.f_message = {type: :error, message: "There was a server error" }
            self.login_state = :return_failed
        end

    end

end

I definitely know that details is correctly formatted so that's not an issue.

I guess in the end, it boils down to is whether it's

  1. opal-jquery sending the post request incorrectly

  2. sinatra improperly parsing the request.

I'm not sure which one it is, but I'm inclined to believe it's the former because it was working fine before I switched to using react.rb for the front end.


Solution

  • After following the advice from this, specifically I'm doing:

    before do
      request.body.rewind
      req = request.body.read
      puts req
      puts JSON.parse(req)
    end
    

    I was able to see that the request arrived at the server correctly and as expected. I don't know why but sinatra was mangling the response in such a away that @params came out as

    {"{\"username\":\"some_user\", \"password\":\"some_password\"}"=>nil}
    

    so, in the end I'm doing

    before do
        request.body.rewind
        @request_payload = JSON.parse(request.body.read)
        request.body.rewind
    end
    

    To read out the request body before sinatra gets anything and just reading out the params I need from @request_payload.