I have a search form I'm using with the YP (Yellow Pages) API, coded in Ruby, with Sinatra.
I've managed to connect all the dots getting the search to work on the back-end, but am having trouble connecting the search form to the API call. Everything displays properly on the page, but nothing shows up when I click the submit button.
The code I am using is below:
require 'rubygems'
require 'sinatra'
require 'yp'
# index.rb
get "/" do
# Only run the search if both of our params are available
if params[:location] && params[:term]
client = Yp::Client.new(api_key: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
results = client.search(searchloc: params[:location], term: params[:term], listingcount: 1, sort: 'distance')
erb :index, :locals => {results: results}
end
__END__
@@index
<h1>YP Search</h1>
<form action="/" method="get">
Location: <input type="text" name="location"> <br />
Search Term: <input type="text" name="term" required> <br />
<input type="submit">
</form>
<% if results %>
<% results.each do |result| %>
# Print out the result info
<% end %>
<% else %>
# They haven't searched yet.
<% end %>
As you've written it, you're not passing results to the template. The last call in the block becomes the return value, which is the body passed to the client, so with your code:
This line:
becomes the body. What you want is the rendered template to be the last line, so:
Instance variables are automatically visible to templates so that's all you'd need to do. If you wanted to pass a local variable:
and then remove the
@
from the front of the@results
var in the template.erb :index
is a method call. It says "call the template renderer, use the ERB engine and pass it the:index
template`. The return value of the method is a string. That string can then be used anywhere, just like a normal string, but you'd obviously be most likely to put it at the end of a route block, since you want to return a string.Where you've placed it right now, in the class body, it's just a method call with a result that goes to nowhere. It's the same as doing:
Think of your Sinatra app like it's a class, and then the normal rules of Ruby become clearer to apply :)
I cloned your Git repo and found a few problems:
in the gemspec:
Above is how I changed the yp.gemspec file, but personally I don't put development dependencies in the gemspec, but in the Gemfile.
I think it's easier to manage and separates things better. Instead of running
bundle install
I runbundle install --binstubs --path vendor
as it puts everything in the local project directory. That way all projects are sandboxed from each other and you'll notice if you've missed anything out. To run the app I usedbundle exec ruby index.rb
.Use
ruby -c filename
to check for syntax errors. First thing to try when you get errors on load.end
.I also added in a halt if the params aren't given, but you could also use an error handler or pass the the error into the template to inform the user. YMMV.
I'm guessing this should be secret. Best thing is probably to get a new one, and never hardcode it and never check it in to Git. I use a file that's not tracked by Git and is loaded into the environment variables, e.g.
I add this into the Rakefile and run the app from the rack file, e.g.
from the commandline:
and you'll probably want to add a
config.ru
.