Indexing Typescript Todo Entities with Lunr | Task

Ole Ersoy
May - 03  -  2 min

Scenario

We have Todo entities defined using this interface.

interface Todo {
    gid?: string;
    id?: string;
    complete: boolean;
    title: string;
}

And we have a few instances of it:

const TODO_ID_1 = '1';
const TODO_ID_2 = '2';
const TODO1: Todo = {
    id: TODO_ID_1,
    complete: false,
    title: 'You complete me!'
};
const TODO2: Todo = {
    id: TODO_ID_2,
    complete: true,
    title: 'You completed me!'
};
let todos: Todo[] = [TODO1, TODO2];

And we want to index these using Lunr.js so that we can search for Todo entities.

Approach

First we need to add lunr and @types/lunr to our Stackblitz.

Then create the index like this by passing a callback function to lunr that will index the Todo fields complete and title .

function initializeSearchIndex(todos: Todo[]): lunr.Index {
    const idx: lunr.Index = lunr(function () {
            this.field('complete');
            this.field('title');
            todos.forEach((todo) => {
                this.add(todo);
        });
    });
    return idx;
}

Once we have the index we can use it to search for Todo instances.

const idx = initializeSearchIndex(todos);
const idxResult: lunr.Index.Result[] = idx.search('false');

And if we console.log the idxResult we see that it contains the incomplete Todo instance reference with ref id 1:

[
  {
    "ref": "1",
    "score": 0.693,
    "matchData": {
      "metadata": {
        "fals": {
          "complete": {}
        }
      }
    }
  }
]

So we need to map this result using our todos array.

function search(query: string) {
    const results = idx.search(query);
    return results.map((result) => {
        return todos.find((todo) => result.ref === todo.id);
    });
}

And now we can search for our Todo instances.

const searchResult = search('false');
//console.log(searchResult);

Now our search result contains the Todo instance with complete set too false.

[
  {
    "id": "1",
    "complete": false,
    "title": "Firefly Semantics Slice Rocks!!"
  }
]

Demo