Query parameter off model attribute

Hello,

Been trying to clean up my code with how I’m handling a query parameter on my controller and thinking there’s a better way. I have an attribute selectedLocation which is either null or a ref to an Ember Data object. I want a query parameter location tied to the selectedLocation’s ID. I’ve gotten this working in the past but it required lots of boiler plate to get it working using a setter and getter plus other stuff. Docs don’t appear to touch on this but it “feels” like something we ought to be able to do. Anyone have experience doing this? Maybe I’m just missing a simple pattern…

Thanks!

I think something like this should work because you don’t have to mark Ember Data model properties as @tracked

import Controller from '@ember/controller';
import { alias } from '@ember/object/computed';

export default class PostsController extends Controller {
  @alias ('model.selectedLocation ') location;
  queryParams= ['location'];
}

So one thing I’ve done in the past was bind query params directly to properties on an injected service (I think this only works if the query params are on the controller and not managed by the route also btw). It looked like this:

  sidebar: service(),
  queryParams: {
    'sidebar.open': {
      replace: true,
      scope: 'controller',
      as: 'sidebar'
    },
    'sidebar.view': {
      replace: true,
      scope: 'controller',
      as: 'sbview'
    },
   }

I’m sure you could do something similar with a model prop instead of a service prop.

Thanks for the suggestion. Doesn’t work at all unfortunately when I try it out in my controller. Is that example code for your route? Wondering even if it did work I’d still need my getter/setter that I’m doing since I need to update selectedLocation based on the changed ID in the query param.

Thanks anyway :slight_smile:

Just to help others with similar situation here’s how I’m doing it.

export default class Index extends Controller {
  // Should be the id of the selectedLocation record:  /?location=4  
  queryParams  =  ['location'];

  // Tied to a dropdown of location Ember Data records. 
  selectedLocation = null;

 ...

  @computed('selectedLocation')
  get location() {
    return isNone(this.selectedLocation) ? null : this.selectedLocation.get('id');
  }

  set location(locationOrId) {
    this.setLocationFromParamTask.perform(locationOrId);
  }

  ...

  @task(function * (locationId) {
    // For some reason Ember query params tries to set their value multiple times.
    yield timeout(250);

    let location = isNone(locationId) ? null : yield this.fetchLocationTask.perform(locationId);
    this.send('selectLocation', location);
  }) setLocationFromParamTask;

  @task(function * (locationId) {
    let locations = yield this.get('model.locationsTask');
    return locations.findBy('id', locationId);
  }) fetchLocationTask;

  ...

  @action
  selectLocation(location) {
    this.set('selectedLocation', location);
  }
}