Vue-instantsearch: Case insensitive matching of route values and state.menu using user-friendly URLs

I have a vue-instantsearch implementation where I am using ais-instant-search with various other ais components (including ais-menu)

I have configured the routing property of ais-instant-search to be the following and this works perfectly, allowing me to synchronise route and state using the user-friendly URLs approach

{
  router: historyRouter(),
  stateMapping: {
    stateToRoute (state) {
      return {
        query: state.query,
        cat1: state.menu && state.menu.cat1,
        cat2: state.menu && state.menu.cat2,
        cat3: state.menu && state.menu.cat3,
        sort: state.sortBy
      }
    },
    routeToState (route) {
      return {
        menu: {
          'cat1': route.cat1,
          'cat2': route.cat2,
          'cat3': route.cat3
        },
        query: route.query,
        sortBy: route.sort
      }
    }
  }
}

The issue is that I would like to improve this by ensuring that all values are transformed to lowercase when they are mapped to the route. Once again this seems quite simple (just add .toLowerCase() to all the values in the stateToRoute function).

However the problem arises when you then need to map from routeToState as the values are now all in lower case and therefore do not match the values in state as the matching process is case sensitive.

Has anybody had a similar issue before and have a solution?

Thanks

Hi @chris.miles

The way I would solve this issue is by implementing a simple object that maps a category to it’s lowercase equivalent

So in your case:

    const mapping = {
      "camera category": "Camera Category",
      "phone category": "Phone Category"
    }

    function getCategorySlug(name) {       
      return name.toLowerCase()
    }

    function getCategoryName(slug) {
      return mapping[slug];
    }

Then in your routing config, do this:

  stateMapping: {
    stateToRoute (state) {
      return {
        query: state.query,
        cat1: state.menu && getCategorySlug(state.menu.cat1),
        cat2: state.menu && getCategorySlug(state.menu.cat2),
        cat3: state.menu && getCategorySlug(state.menu.cat3),
        sort: state.sortBy
      }
    },
    routeToState (route) {
      return {
        menu: {
          'cat1': getCategoryName(route.cat1),
          'cat2': getCategoryName(route.cat2),
          'cat3': getCategoryName(route.cat3)
        },
        query: route.query,
        sortBy: route.sort
      }
    }
  }
}

Let me know if this helped.

HI Youcef,

Thanks for your solution.

Unfortunately the possible category values are completely dynamic so it would make it difficult to maintain a mapping of sorts.