3

I have a Rails app I'm working on that is a database of APIs: http://hapily.herokuapp.com/ It already has a working search box I've made in Rails, but I'd like to use angular.js to make the search work without leaving the home page. I can't seem to get angular to connect with my rails database. Here's the search form:

<form class="navbar-search" method="get" action="/apis/search" id="search">
    <input type="text" class="search-query" placeholder="Search" name="query" ng-model="query">
</form>

Here's the search method in my apis_controller.rb:

def search
    @results = Api.where("name ILIKE ? OR description ILIKE ? OR category ILIKE ?", "%#{params[:query]}%", "%#{params[:query]}%", "%#{params[:query]}%").all
end

Here's my js search controller:

app = angular.module("Hapily", ["ngResource"])

@SearchCtrl = ($scope, $resource) ->
  Search = $resource('/search/:query', {query:"@query"})
  $scope.results = Search.get()

Here's my current search page view:

<% @results.each do |api| %>
<div class="box" ng-repeat="result in results | filter:query">
    <div class="api-favicon">
    <%= image_tag("http://www.google.com/s2/favicons?domain_url=" + api.url) %>
    </div>
    <%= link_to api.name, apipage_path(:id => api.id) %>
    <p class="category"><%= api.category %></p><br><br>
    <%= api.description %><br><br>

    Votes: <%= Vote.where("api_id = ?", api.id).count %>
    <%= link_to image_tag('grayarrow.gif'), votes_path(api_id: api.id, value: 1), method: :post  %>
</div>
<% end %>
</div>

Right now all the APIs are displayed on the index page, and when a user types a term into the search box in the navbar, they are directed to /search?query=searchterm How should I change my code to get matching APIs to render on the index page? I'm pretty new at angular and rails so I may be way off here. Any help is appreciated!

Sara
  • 2,729
  • 7
  • 22
  • 30

1 Answers1

2

You are using server side filtering

def search
    @results = Api.where("name ILIKE ? OR description ILIKE ? OR category ILIKE ?", "%#{params[:query]}%", "%#{params[:query]}%", "%#{params[:query]}%").all
end

along with client side filtering

<div class="box" ng-repeat="result in results | filter:query">

You only need one of these.

For only using AngularJS filtering start by renaming your server controller something like display instead of search and let results be everything

def display
    @results = Api.all
end

Then your js controller can be:

app = angular.module("Hapily", ["ngResource"])

@SearchCtrl = ($scope, $resource) ->
  Search = $resource('/display/')
  $scope.results = Search.get()

and your page (notice the input I added, and the fact that angular does the looping not ruby):

<input ng-model="query"/> 
<div class="box" ng-repeat="result in results | filter:query">
    <div class="api-favicon">
    <%= image_tag("http://www.google.com/s2/favicons?domain_url=" + api.url) %>
    </div>
    <%= link_to api.name, apipage_path(:id => api.id) %>
    <p class="category"><%= api.category %></p><br><br>
    <%= api.description %><br><br>

    Votes: <%= Vote.where("api_id = ?", api.id).count %>
    <%= link_to image_tag('grayarrow.gif'), votes_path(api_id: api.id, value: 1), method: :post  %>
</div>
basarat
  • 261,912
  • 58
  • 460
  • 511