user1903663
user1903663

Reputation: 1725

Render in HTML result of ajax call with Ruby / Sinatra

I have a jquery which uses parameters to query the Plivo api.

$(".localsearch").click(function() {
        var country_iso = $("#local").val();
        var region = $("#region").val();
        var prefix = $("#prefix").val();
        $.ajax({
        type: "GET",
        url: "/local/data",
        data: { 'country_iso' : country_iso,  'region' : region,  'prefix' : prefix },
        success: function(data){
            window.location.href = '/local'
        }
      });
});

The ruby code block receives the parameters and queries through the api

get '/local/data' do
      country_iso =  params[:country_iso]
      region = params[:region]
      prefix = params[:prefix]
      p = RestAPI.new(AUTH_ID, AUTH_TOKEN)
      params = {'country_iso' => country_iso, 'region' => region, 'prefix' => prefix, 'limit' => 1}
      warn params.inspect   
      response = p.get_number_group(params)
      obj = response.last
      puts obj["objects"][0]["stock"]
      puts obj["objects"][0]["region"]
      @stock = obj["objects"][0]["stock"]
      @region = obj["objects"][0]["region"]
      @prefix = obj["objects"][0]["prefix"]
      @voice_rate = obj["objects"][0]["voice_rate"]

      erb :local
end

The parameters are passed and the terminal console shows a successful result:

{"country_iso"=>"US", "region"=>"NY", "prefix"=>"646", "limit"=>1}
57  # = puts obj["objects"][0]["stock"]
New York, UNITED STATES # = puts obj["objects"][0]["region"]

My question is this: how can I "echo" the ressults on my local.erb page? Local.erb below:

<h2>Your search returned the following result</h2>
        <ul>
          <li><span class="fixed">Stock:</span><span class="fixed"><%= @region %></span></li>
          <li><%= @region %></li>
          <li><%= @prefix %></li>
          <li><%= @voice_rate %></li>
          <li><input type="submit" class="buynumber" value="Buy this number" /></li>
          </ul>

The results are only printed in the terminal with puts .. and nothing appears on the local.erb page when the jquery redirects the user to local.erb.

Thank you for considering this!

Upvotes: 2

Views: 3640

Answers (1)

ian
ian

Reputation: 12251

@akonsu gives a good response. Don't redirect at the end of an AJAX call to a route.

There's also 2 ways to do this:

  • Send some data, you get a response as an echo, which you then use to confirm and display
  • Send some data, you get a response as an echo, which you then use to confirm, but you use the sent data to display.

You've got the sending of the data done.

Getting a response as an echo.

Change the last line of the get '/local/data' route to:

  halt 200, {stock: @stock, region: @region, prefix: @prefix, voice_rate: @voice_rate}.to_json
end

It's better to use halt than just leaving it as the last statement because you get to add a status code as well, which is helpful when doing things other than GET.

If you still needed to render the route to a browser and not just an AJAX call you could do something like:

  if request.xhr? # XHR is the X in AJAX, so this is the AJAX call
    halt 200, {stock: @stock, region: @region, prefix: @prefix, voice_rate: @voice_rate}.to_json
  else # this would serve browsers, you could also filter by content type… YMMV
    erb :local
  end
end

In your AJAX request, add a couple of lines to make sure you request JSON (see jQuery-ajax-settings)

$(".localsearch").click(function() {
    var country_iso = $("#local").val();
    var region = $("#region").val();
    var prefix = $("#prefix").val();
    $.ajax({
    type: "GET",
    url: "/local/data",

    accepts: "application/json",
    dataType: "json",

    data: { 'country_iso' : country_iso,  'region' : region,  'prefix' : prefix },
    success: function(data){
        window.location.href = '/local'
        // this is the bit where you render stuff
    }
  });

});

Confirm the data is correct

I'll leave that to you. You could just check the status code and trust the rest, or you could use a checksum or hash of somekind… that's for you to decide and implement.

Displaying the response.

Add a div with id search_echo_placeholder (or whatever) to the search page, where you want the output to show.

In the javascript, do something like this:

display = function(data) {
  var stock, region, prefix, voice_rate, _i, _len, _ref;

  result = "";
  for (_i = 0, _len = data.length; _i < _len; _i++) {
    _ref = data[_i], stock = _ref.stock, region = _ref.region, prefix = _ref.prefix, voice_rate = _ref.voice_rate;
    result += "<li>" + stock + "</li>";
    result += "<li>" + region + "</li>";
    result += "<li>" + prefix + "</li>";
    result += "<li>" + voice_rate + "</li>";
  }
  result = "<ul>" + result + "</ul>";
  return result;
};

// add this to the AJAX function
  dataFilter: display,
  success: function(result, status, xhr) {
    return [ $("#search_echo_placeholder").html(result) ];
  },

Something along those lines. I've liberally copy and pasted and made up bits so don't rely on this verbatim, it's there to give you an idea.

Upvotes: 3

Related Questions