Can I add a custom helper to a {{link-to}} component?

I have a couple of places in my application where I add some query-params to a {{link-to}} helper. They have gotten quite unwieldy and ‘hardcoded’ for example:

{{#link-to 'custSearch.results' (query-params dateFrom=dateFrom dateTo=dateTo listType=0
    coc=null dest=null conID=null spec=null apptWithin=null tlSource=c1source deleted=null hours=hours period=period grade=model.name_id)}}

This might be used a few times on a single page so I thought I would create a helper that made all of the params null unless I passed in the desired namedArgs.

I created the helper but I can’t seem to add it without generating an error. For example I have tried:

{{#link-to 'custSearch.results'  {{helper dateFrom=dateFrom}} }}

and

{{#link-to 'custSearch.results' (helper dateFrom=dateFrom)}}

however both create errors and stop the page from loading. I have used custom helpers elsewhere by just using {{helpername}} but that was in the template, not in another component.

Am I barking up the wrong tree?

You may extend the LinkComponent to make it work as you wish (see ‘@ember/routing/link-component’).

Hi nik, thanks for the reply. I’m not very experienced and unsure what you mean by extending the link component. Would you mind expanding a bit?

It looks like your link-to has many static values. I think you should make a new component that renders this link-to.

For example:

{{#search-link-to dateFrom=dateFrom dateTo=....}}
 ...
{{/search-link-to}}

And then you would use the full link-to in the component template.

{{! templates/components/search-link-to }}

{{#link-to 'custSearch.results'
  (query-params
    dateFrom=dateFrom
    dateTo=dateTo
    listType=0
    coc=null
    dest=null
    conID=null
    spec=null
    apptWithin=null
    tlSource=c1source
    deleted=null
    hours=hours
    period=period
    grade=model.name_id)}}
  {{yield}}
{{/link-to}}
1 Like

One thing to note is that the query-params helper is simply an object that has isQueryParams: true. So you can make your own helper and use it in place.

In future it might check the object type (last time I looked this class never existed, it was just but for now it is just checking isQueryParams.

Here is a helper I use so that the router clears all params for the link.

import { helper } from '@ember/component/helper';
import Object from '@ember/object';
import { assign } from '@ember/polyfills';

export function explicitQueryParams(params, hash) {
  let values = assign({}, hash);
  values._explicitQueryParams = true;

  return Object.create({
    isQueryParams: true,
    values,
  });
}

export default helper(explicitQueryParams);

I then use the property I have set here in the router to clear them, will paste just so the example is complete, however it isn’t relevant to what you want.

const Router = Ember.Router.extend({
  ...
  _hydrateUnsuppliedQueryParams(state, queryParams) {
    if (queryParams._explicitQueryParams) {
      delete queryParams._explicitQueryParams;

      return queryParams;
    }

    return this._super(state, queryParams);
  },
});

Here is how the helper is used:

{{link-to (t 'pending_reviews') 'content-reviews' (explicit-query-params)}}

{{link-to (t 'pending_reviews') 'content-reviews' (explicit-query-params search='test')}}

In my case this means any previous query params are cleared when clicking this link whereas the default (read: annoying) behaviour is to add any current params to that link for some reason.

1 Like

Hi Rob, thanks for your advice.

Your solution actually suits me down to the ground. I didn’t want to switch off the sticky params because in most cases they suit the use case for my app but on these particular templates they cause a problem. The ability to switch the sticky params off on link to link basis is superb.

I actually wonder if that shouldn’t be a default helper.

Hi @sorvah,

I would try to pass to the link-to an object as queryParam built from the controller as a computed property where you get the queryParams array setting all properties to null value except the ones you want, also you can make the same with an action which does the same through the transitionToRoute method.

There are old issues about query params and they even ignored bugs with the excuse of “but routeable components”. I think I still have mixins fixing bugs. In discussions though the query params are meant to be reworked and improved a lot I think, no idea when though.