Reputation: 1047
So what I've done is made a page using Sinatra where a user can enter info, and when that info is submitted I grab it with a post method, I then use that info that they submitted to make a search call to the Yelp api, I get a response, and I want to update the page with the results from that response without it going to a different page.
So far I can get the user input, make the search, and receive the search results, but after that I try to make an ajax call to the post method, return a erb to the ajax call, and insert that erb file in a div at the bottom of the page. I keep getting a 500 internal server error and I'm not sure why. Is there an easier or more straigh forward way to accomplish what I'm trying to do? My code is below.
Main.rb File:
require 'sinatra'
require 'yelp'
require 'openssl'
require 'json'
require 'net/http'
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
get '/' do
erb :layout
end
client = Yelp::Client.new({ My keys
})
hash = {limit: 5, category_filter: 'food'}
locale = { lang:'eng' }
post '/food' do
name = params[:name]
city = params[:city]
nationality = params[:nationality]
meal = params[:birth_time]
stork = params[:stork]
searchStr = city + " " + name + " " + nationality + " " + meal
response = client.search(searchStr)
@business = response.businesses[0].name
@business_img = response.businesses[0].image_url
@url = response.businesses[0].url
@rating_img = response.businesses[0].rating_img_url
erb :baby
end
Layout.erb file:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="/script.js"></script>
</head>
<body>
<form method="POST" action="/food" id="babyDetails">
<p> Name of Child: <input type="text" name="name"></p>
<p> Hometown: <input type="text" name="city"></p>
<p>
Nationality:
<select name="nationality">
<option value="American">American</option>
<option value="Chinese">Chinese</option>
<option value="Greek">Greek</option>
<option value="Bakery">Fairy</option>
<option value="Haitian">Haitian</option>
<option value="Indian">Indian</option>
<option value="Japanese">Japanese</option>
<option value="Mexican">Mexican</option>
</select>
</p>
<p>
Time of Delivery:
<select name="birth_time">
<option value="morning">Morning</option>
<option value="afternoon">Afternoon</option>
<option value="night">Night</option>
</select>
</p>
<p>
I Want The Stork To Deliver My Baby? <input type="checkbox" name="stork" value="yes">
</p>
<input type="submit" value="Where Can I Find My Baby?" id="submitBtn"/>
</form>
<div id="babyResult">
</div>
</body>
</html>
Baby.erb File:
<div>
<h1>You can find your baby at:</h1>
<br />
<h5><%= @business %></h5>
<img src='<%= @business_img %>'/>
</div>
script.js File:
$(document).ready(function() {
$("#submitBtn").click( function(){
console.log("Works");
$('#babyResult').html("")
$.ajax({
type: 'post',
url: '/food',
success: function(result) {
$('#babyResult').html(result);
}
});
});
});
Upvotes: 1
Views: 1095
Reputation: 581
I didn't test, but I think that you have two problems.
You are binding your AJAX call to a submit button, but you don't return false;
at the end of the callback. After the click
event has been processed by your Javascript code, it will bubble up and the browser will execute a normal form submission. So the end result is two POST requests for one click.
You can fix that by either adding return false;
after the AJAX call, or by using a <button>
instead of an <input type="submit">
element, for instance.
You are using global objects like client
without a proper locking mechanism. I don't see the yelp
gem mentioning anything about being thread-safe, so we must assume that it isn't. If you have two requests at the same time, client
could be accessed simultaneously by two different threads, and fail. You must always be wary of the fact that in Sinatra, each request can be processed in a different thread, so two simultaneous requests on the same route can be processed simultaneously.
You can either create a new Yelp::Client
object in the route (i.e., every time you need one), or use a mutex
before calling a method on your client
.
Upvotes: 2
Reputation: 309
(Sorry don't have reputation to comment only, but I want to help) Don't really have time to answer today but i will leave you a similar example.
https://github.com/pgaspar/oqfc
In the folder oqfc/public/js/ajax.js
I send to the server which suggestion was voted (up button or down button) and I recieve back from the server the vote count.
Hope it helps, will get to you tomorrow.
--- UPDATE ---
Instead of inserting the new rendered code to #babyResult, make a console.log with it and show it
Upvotes: 0