DEV Community

Michal Bryxí
Michal Bryxí

Posted on

Add fulltext filter support to ember-cli-mirage

There is an open issue in ember-cli-mirage that tries to bring filter support for JSONAPI Serializer. Unfortunately my tests needed this functionality now. More specifically they needed a fulltext filtering support.

Here is a solution I came up with.

First make sure that factories for all endpoints produce something that we can filter on. I simply created attribute fulltext that returns a string of things that I want to filter on:

// mirage/factories/item.js import faker from "faker"; export default Factory.extend({ fulltext() { return `${this.name}`; }, name() { return faker.commerce.productName(); }, }); 
Enter fullscreen mode Exit fullscreen mode
// mirage/factories/customer.js import { Factory } from "ember-cli-mirage"; import faker from "faker"; export default Factory.extend({ fulltext() { return `${this.firstName} ${this.lastName}`; }, firstName() { return faker.name.firstName(); }, lastName() { return faker.name.lastName(); }, }); 
Enter fullscreen mode Exit fullscreen mode

Then teach mirage to filter on attribute filter when querying for collections:

// mirage/config.js import Response from "ember-cli-mirage/response"; export default function() { this.namespace = "api/v1/"; this.get("/customers", fulltextFilter); this.get("/items", fulltextFilter); } function fulltextFilter(schema, request) { // example: request.url = '/api/v1/items?filter%5Bfulltext%5D=Automobil' // So we make it so that `subject = 'items'`. This way we can use this function for any endpoint let subject = request.url.split(/[/?]/)[3]; // If mirage got request for fulltext filter let fulltextParam = request.queryParams["filter[fulltext]"] if (fulltextParam) { // I'm making the search case in-sensitive let fulltextParamCI = fulltextParam.toLowerCase(); // Filter out from all the records return schema[subject].all().filter(function(record) { // Leave only those which `fulltext` attribute contain our string return record.attrs.fulltext.toLowerCase().indexOf(fulltextParamCI) !== -1; }); } // If no filter is applied, return all records for given `subject` return schema[subject].all(); } 
Enter fullscreen mode Exit fullscreen mode

Notes

  • This is very primitive fulltext search, you might need to make it more fancy for your use-case.
  • On the backend I'm using jsonapi-resources@0.9.10 and I'm not exactly sure why it requires the query param as literal string of filter[fulltext] and not nested array. Your API might be different.

Top comments (0)