AngularJS Wikipedia Search App – Part Two

Continued from Part One

Build a Wikipedia Search App With AngularJS

Part Two – Use Output

So, if everything went as expected in the first part, you should be getting output in your console.

Now we need to actually display the output on the page.


The JavaScript

We first need to modify our app so that it does something with the data besides printing to the console.

// app.js

$scope.results = [];

this.searchTerm = '';
_this.search = function() {
  $.getJSON(API_PATH + '?action=opensearch&callback=?&search='
  + _this.searchTerm, function(json){
    $scope.results = json;
  });
};

You can view the full code for the (completed) app here.

Here we’re adding the results to a $scope variable, so that we can access it within our scope (i.e. our HTML).

Try displaying this in your HTML (anywhere within the controller block) using {{ results }}.

You should find that, although it does work, it doesn’t do so on the first submit.

This is because of Angular’s Digest Cycle. The $scope variable is being updated, but after Angular has already completed its cycle.

Therefore, the changes won’t be detected by Angular until the next Digest Cycle.

Normally this will occur automatically, but in cases where it doesn’t, we can use $scope.apply(); to apply the changes immediately.

Add that line to your function so that it looks like this:

$scope.results = json;
$scope.$apply();

The $scope.results variable will now update immediately on submit.

The HTML

We’re going to add the below code between the <tbody> tags in index.html.

<tbody>
// index.html
 <tr ng-repeat="title in results[1]">
   <td class="col-xs-3"><a ng-href="{{ results[3][$index] }}">{{ title }}</a></td>
   <td class="col-xs-9">{{ results[2][$index] }}</td>
 </tr>

</tbody>

While you could create separate objects for the title, description, and urls, here I have kept them within the same object, just as it’s returned from the API.

The JSON object return from the API call is structured as follows:

Array[4]
  [0] "your search term"
  [1] Array containing Titles of results
  [2] Array containing Descriptions of results
  [3] Array containing URLs to the article

The default returns only the top 10 results, so you should have three arrays, each of length 10.

So, in the above code, title in results[1] is iterating through the array of titles.

We want the titles, descriptions, and URLs for each result to show up together, so we are only using ng-repeat once.

We can then use Angular’s built-in $index object to reference the corresponding values from the other arrays.

results[3][$index] is the URL for the result, and results[2][$index] is the description for the result.

Note that you should use ng-href instead of href when your URL is loaded dynamically via Angular.

While the link will still work properly if you don’t, it will print an annoying 404 error in your console.

If you’re curious, this is because HTML is processed before the Angular app is compiled. So HTML looks at href and sees some weird shit it doesn’t understand, {{ results[3][$index] }}, which returns a 404.

Using ng-href means that the value of the URL will be processed by Angular at the time the app is compiled.

Now your app should be fully functional, updating immediately on submit.

A Little Something Extra!

So now our search works, it looks nice, but…it’s always fun to do a little something extra!

We’re going to update the app so that it will begin displaying results as soon as you start typing.

This is actually really simple with Angular’s $watch service.

We’re going to take the this.search function and replace it with the following code:

$scope.$watch('ctrl.searchTerm', function(newVal, oldVal) {
  $.getJSON(API_PATH + '?action=opensearch&callback=?&search='
  + newVal, function(json){
    $scope.results = json;
    $scope.$apply();
  });
});

Here we’ve just taken all of the code from our this.search function and placed in inside $scope.$watch.

This means that we can actually remove the submit button from our index.html file, because we won’t be using it anymore.

  1. The first parameter in $scope.$watch is the name used as ng-model for the input in your index.html file.
  2. The second parameter is a function with the parameters newValue and oldValue. We’re not actually doing anything with the old value here, but it’s good to know for future reference.
Now have a fully functional and dynamic AngularJS Wikipedia search app!

angularjs wikipedia search app

Yay!

I always recommend that if you run into problems to Google that Shit, but feel free to ping me @kimberlythegeek if you have any questions.

You can view the code for the (completed) app on my GitHub repository, and a live example on GitHub Pages.

Syntax Highlighting by EnlighterJS

About the Author

Kimberly is a software engineer, and currently works as a Test Engineering Intern for Mozilla.

While she always enjoys learning new technologies, her current focus is python, and when she has free time (she doesn't), Angular & Node.

When not coding, Kimberly spends time with her three young boys in Durango, CO.