Curious
Curious

Reputation: 2981

Search UI for Solr with Angular JS

I am trying to learn Solr and Angular JS (I don't have much experience in javascript either), by trying to write a simple search UI for Solr.

My index.html is here

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
    <title>Learn AngularJS - Instant Search</title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
    <script src="script.js"></script>
  </head>
  <!-- Initialize a new AngularJS app and associate it with a module named "instantSearch"-->
  <body ng-app="instantSearch" ng-controller="SearchController">
    <div class="bar">
      <!-- Create a binding between the searchString model and the text field -->
      <input type="text" ng-model="searchString" placeholder="Enter your search terms" />
    </div>
    <ul>
      <!-- Render a li element for every entry in the items array. Notice
         the custom search filter "searchFor". It takes the value of the
         searchString model as an argument.
       -->
      <li ng-repeat="i in items | searchFor:searchString">
        <p>{{i.name[0]}}</p>
      </li>
    </ul>
  </body>
</html>

and my controller script.js is here:

// Define a new module for our app
var app = angular.module("instantSearch", []);

// Create the instant search filter
app.filter('searchFor', function(){
  // All filters must return a function. The first parameter
  // is the data that is to be filtered, and the second is an
  // argument that may be passed with a colon (searchFor:searchString)
  return function(arr, searchString){
    if(!searchString){
      return arr;
    }
    var result = [];
    searchString = searchString.toLowerCase();

    // Using the forEach helper method to loop through the array
    angular.forEach(arr, function(item){
      if(item.name[0].toLowerCase().indexOf(searchString) !== -1){
        result.push(item);
      }
    });
    return result;
  };
});

// The controller
function SearchController($scope, $http){
  // The data model
  $http.get('http://localhost:8983/solr/gettingstarted/select?q=*:*&wt=json').
    success(function(data) {
      console.log(data);
      $scope.items = data.response.docs;
    }).
    error(function(data, status, headers, config) {
      console.log('error');
      console.log('status : ' + status); //Being logged as 0
      console.log('headers : ' + headers);
      console.log('config : ' + JSON.stringify(config));
      console.log('data : ' + data); //Being logged as null
    });
}

As you see I am trying to invoke a Solr search using GET. But this is not doing anything, the control in fact goes into the error block of the get call.

In Firebug however I see that the GET request is being fired and I do the expected output in its response!

Any clues, what am I doing wrong here?

Upvotes: 0

Views: 4529

Answers (3)

Curious
Curious

Reputation: 2981

Looks like it was a CORS issue. I have finally had this working for me. Reproducing here, in case anyone comes looking!

root.js

angular.module("root", ["filters", "ngResource"])
  .controller("index", ["$scope", "$resource", "$location",
         function ($scope, $resource, $location) {
    var srchUrl = $resource($location.protocol() + "://" + 
                 $location.host() + ":" + $location.port() + 
                 "/solr/campainFlowChartCol/select?q=*:*&wt=json");
    restRes = srchUrl.get(function(data) {
      $scope.allDocuments = data.response.docs;
    });
  }]);

filters.js

angular.module("filters", [])
  .filter("searchFilter", function () {
    return function(docs, srchStr) {
      if(!srchStr){
        return docs;
      }
      var results = [];
      srchStr = srchStr.toLowerCase();
      angular.forEach(docs, function(doc){
        if(doc.name[0].toLowerCase().indexOf(srchStr) !== -1 ||
           doc.author[0].toLowerCase().indexOf(srchStr) !== -1 || 
           doc.id.toLowerCase().indexOf(srchStr) !== -1 || 
           doc.cat[1].toLowerCase().indexOf(srchStr) !== -1) {
          results.push(doc);
        }
      });
      return results;
    };
  });

solrSearch.html

<html ng-app="root">
  <head>
    <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"></link>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"/></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-resource.js"></script>
    <script src="root.js"></script>
    <script src="filters.js"></script>
  </head>
  <body>
    <div ng-controller="index">
      <p>Look For: <input type="text" class="form-control" ng-model="srcStr" placeHolder="Enter your search string"/></p>
      <table class="table table-striped">
        <thead style="font-weight: bold;">
          <td>ID</td>
          <td>Category</td>
          <td>Name</td>
          <td>Author</td>
          <td>Genre</td>
          <td>In-Stock</td>
          <td>Price</td>
          <td>Pages</td>
        </thead>
        <tbody>
          <tr ng-repeat="doc in allDocuments | searchFilter:srcStr">
            <td>{{doc.id}}</td>
            <td>{{doc.cat}}</td>
            <td>{{doc.name[0]}}</td>
            <td>{{doc.author[0]}}</td>
            <td>{{doc.genre_s}}</td>
            <td>{{doc.inStock[0]}}</td>
            <td>{{doc.price[0]}}</td>
            <td>{{doc.pages_i}}</td>
          </tr>
        </tbody>
      </table>
    </div>
  </body>
</html

Upvotes: 1

ozdemir
ozdemir

Reputation: 81

There are a lot of mistakes in your code.

First : you didn't include "app.js" file into index.html

Second : $http.get('http://localhost:8983/solr/gettingstarted/select?q=:&wt=json') should be $http.get('http://localhost:8983/solr/gettingstarted/select?q='+ $scope.searchString +'&wt=json')

Upvotes: 0

Austin Greco
Austin Greco

Reputation: 33554

I see you have a fullpathed url, is the UI on a different domain/port? If so, you'll have to setup cross domain headers, or proxy it on the server.

Also on a side note, you may want to consider upgrading angular version, 1.0.7 is very old.

Upvotes: 0

Related Questions