TAGS :Viewed: 10 - Published at: a few seconds ago

[ Ember not updating query parameters when calling transitionToRoute() right after ]

In my application, I have an overall controller that manages state for a portion of the application, called SimpleSearch.

Within SimpleSearch, I have multiple SimpleSearchOptions, that display a list of choices to a user.

A user can select an option, and that selection is an action that is called from the view, that bubbles up to the SimpleSearchOptionController:

App.SimpleSearchOptionController = Ember.ObjectController.extend({
//....
    select: function (option) {
        option.queryName = this.get('queryName');
        this.get('simpleSearch').setSelection(option);
        this.set('selectedOption', option);
        this.set('hasSelectedOption', true);
        this.send('transitionToNextOption');
    },
//....

This action calls this.get('simpleSearch').setSelection(option);, which registers the selection with the SimpleSearchController:

App.SimpleSearchController = Ember.ObjectController.extend({
//....
    setSelection: function (option) {
        this.set(option.queryName, option.value);
        this.get('selectedOptions').set(option.queryName, option.value);
        this.get('model').notifyPropertyChange('selectedOptions');
        this.checkIfAllOptionsSelected();
    },
//....

The important line in there is: this.set(option.queryName, option.value);.

After it registers the selection, it moves to the next option, and if there isn't one, it skips to the results of the search. That is called from this.send('transitionToNextOption');

App.SimpleSearchOptionController = Ember.ObjectController.extend({
//....
    transitionToNextOption: function () {
        var nextOptionId = parseInt(this.get("id")) + 1;
        var numOfOptions = this.get('simpleSearch.numOfOptions');
        if (nextOptionId < numOfOptions) {
            this.transitionToRoute('simpleSearchOption', nextOptionId);
        }
        else {
            this.transitionToRoute('simpleSearchResults');
        }
    },
//....

In setSelection() above, the line this.set(option.queryName, option.value); is setting a query parameter's value. This only works correctly, and the url gets updated accordingly for all options, when I'm not transitioning to a different route.

If I comment out the lines:

else {
    this.transitionToRoute('simpleSearchResults');
}

Setting the property (this.set(option.queryName, option.value);) actually has the side effect of Ember updating the query parameter in the URL, which is my intent. If I include that line, and transition to a different route after setting that variable, the query parameter is not updated.

I was stepping through Ember's code, but I can't quite follow how it handles this. It continues into _doTransition(), and I've noticed that the transition to the route 'simpleSearchResults' always happens before the queryParams are passed through.

How do I get Ember to update the query parameter before it transitions to 'simpleSearchResults'?

Thank you for any and all help.

Answer 1


I solved my issue by wrapping the transition in an Ember.run.next() function:

transitionToNextOption: function () {
    var nextOptionId = parseInt(this.get("id")) + 1;
    var numOfOptions = this.get('simpleSearch.numOfOptions');
    if (nextOptionId < numOfOptions) {
        this.transitionToRoute('simpleSearchOption', nextOptionId);
    }
    else {
        var self = this;
        Ember.run.next(function() { self.transitionToRoute('simpleSearchResults'); });
    }
},

I'm assuming, but have not verified, that Ember was queuing up the action to transition to 'simpleSearchResults', and handles the query parameters similarly. Perhaps the transition to a different route was somehow interrupting or overwriting the query parameter being written to the URL.