Last Updated: September 01, 2017
·
821
· bootoo

Using Algolia InstantSearch.js with Angular 4

I'm usually not much of a blogger or community-oriented person, but I just had to blog about my experience with Angular 4 and Algolia InstantSearch.js.

I was developing a project that needed an optimized search service, which is when I found out about Algolia Search from a friend of mine. I wanted to use it but infusing it into my project was difficult because I couldn't find any tutorials, like this one you're reading, that could help me learn Algolia and Angular 4.

Enough of the introduction — let’s go straight into infusing Algolia InstantSearch.js with Angular 4!

First, we have to install Angular CLI for our project:

npm install @angular/cli@latest --save 

After inserting the above code into our command line, we'll create a new project.

ng new alsearch
cd alsearch
ng serve 

Navigate to http://localhost:4200/. The app will automatically reload if you change any of the source files.

You can configure the default HTTP host and port used by the development server with two command-line options :

ng serve --host 0.0.0.0 --port 4201

After playing around with the command line, you can go back to your project and link Algolia InstantSearch.js with your Angular 4 project by inserting the code below into your environment file.

Environment.ts is located in the environment folder, which is located in the src folder /src/environments/environment.ts.

 export const environment = {
 production: false,
 algolia: {
  appId: 'APP_ID',
  apiKey: 'SEARCH_ONLY_KEY',
  indexName: 'getstarted_actors',
  urlSync: false
 }
}; 

After doing that, we need to install the instantsearch.js package so that we can use the different Angolia Search packages.

npm install instantsearch.js --save

If you want to use the Algolia CSS and templates, add the following lines to the head of the index.html file.

<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/instantsearch.js@2.0.0/dist/instantsearch.min.css"> 
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/instantsearch.js@2.0.0/dist/instantsearch-theme-algolia.min.css"> 

Search Component
Our entire search feature will be wrapped up in the search.component.ts, which you can generate with ng g component search. During ngOnInit you configure the InstantSearch with your environment variables and call .start() initialize it. Use declare var instantsearch: any to clear some errors that might be encountered when using InstantSearch.

 import { Component, OnInit } from '@angular/core';
import { environment } from '../../environments/environment';
import * as instantsearch from 'instantsearch.js';
declare var instantsearch: any;
@Component({
 selector: 'search',
 templateUrl: './search.component.html',
 styleUrls: ['./search.component.scss']
})
export class SearchComponent implements OnInit {
 search: any;
 constructor() { }
 ngOnInit() {
  const options = environment.algolia;
  this.search = instantsearch(options);
  this.search.start();
 }
} 

You can build out the Algolia search interface by adding widgets to it. Let’s start by adding a search field and the results (hits) to our component.

this.search.addWidget(
 instantsearch.widgets.searchBox({
  container: '#search-box'
 })
);
// initialize hits widget
this.search.addWidget(
 instantsearch.widgets.hits({
  container: '#hits',
 })
); 

Search HTML
In the template, you can ID the elements you want to replace with the widgets.

<div id="search-box">
 <!-- SearchBox widget will appear here -->
</div>
<div id="hits">
 <!-- Hits widget will appear here -->
</div> 

To use a custom template for the results shown instead of the default plain text, you can use the code below.

You can also add templating to certain widgets with Mustache, and interpolate data with double curly brackets. In the hits widget, I display the actor’s name and image rather than the raw JSON.

 this.search.addWidget(
 instantsearch.widgets.hits({
  container: '#hits',
  templates: {
   empty: 'No results',
   item: `<img src=https://image.tmdb.org/t/p/w300{{image_path}} width="50px">
   Result {{objectID}}:
    {{{_highlightResult.name.value}}}`
  },
  escapeHits: true
 })
); 

Full Code

//search.component.ts
import { Component, OnInit } from '@angular/core';
import { environment } from '../../environments/environment';
import * as instantsearch from 'instantsearch.js';
declare var instantsearch: any;
@Component({
 selector: 'search',
 templateUrl: './search.component.html',
 styleUrls: ['./search.component.scss']
})
export class SearchComponent implements OnInit {
 search: any;
 constructor() { }
 ngOnInit() {
  const options = environment.algolia;
  this.search = instantsearch(options);
  this.search.addWidget(
   instantsearch.widgets.searchBox({
    container: '#search-box'
   })
  );
// initialize custom hits widget
 this.search.addWidget(
  instantsearch.widgets.hits({
   container: '#hits',
   templates: {
    empty: 'No results',
    item: `<img src=https://image.tmdb.org/t/p/w300{{image_path}} width="50px">
    result {{objectID}}:
     {{{_highlightResult.name.value}}}`
    },
    escapeHits: true
   })
 );
 this.search.start();
 }
}

 //search.component.html
<div id="search-box">
 <!-- SearchBox widget will appear here -->
</div>
<div id="hits">
 <!-- Hits widget will appear here -->
</div>

If you have any questions, please leave a comment below!