spacerobot
spacerobot

Reputation: 297

How do you set variable in route and display in template?

I am looking to set a variable for each page that is set to text to display as a dynamic header sort of thing. How would I set a variable in a route and display it in the corresponding template? So far everything I have tried is not working.

Upvotes: 0

Views: 2033

Answers (3)

Ahmet Emre Kilinc
Ahmet Emre Kilinc

Reputation: 6935

You can only pass route variable to the template by using model hook. However, model is called only once. In order to update route variable and see its final value in the template, you need to wrap the variable. After that, you need to update the variable inside wrapped and the referance of the wrapped will not be changed. Your code will be like:

route.js:

model(){
    this._super(...arguments);
    this.set('myWrappedVariable', {myVariable: 1});
    let modelResult = {myWrappedVariable: this.get('myWrappedVariable')};

    return modelResult;
},

actions:{
    increaseVariables(){
        Ember.set(this.get('myWrappedVariable'), 'myVariable', this.get('myWrappedVariable.myVariable')+1);
    }
}

template.hbs

myWrappedVariable: {{model.myWrappedVariable.myVariable}}

Take a look at this twiddle for this usage.

Upvotes: 1

jelhan
jelhan

Reputation: 6328

@Gaurav answer is totally right and should be considered as best practice. However if you have a good reason for setting a variable, which is not the model, in a Route, you could use setupController hook therefore:

import Route from '@ember/routing/route';

export default Route.extend({
  setupController(controller, model) {
    // Call _super for default behavior
    this._super(controller, model);

    // Set a variable on controller
    controller.set('foo', 'bar');
  }
});

As shown in the api docs you could also use setupController to set a variable on another controller by getting an instance of it using controllerFor method. However I would not consider this a good practice, cause if it's not well documented throughout the application, it's quite hard to maintain such code.

As shown by @Ahmet Emre Kılınç's answer you could also use a hash as model. If at least one of it's properties is a Promise, you should return a RSVP.hash(). Otherwise model hook would not block the transition until the Promise is fulfilled.

Upvotes: 0

Gaurav
Gaurav

Reputation: 12806

The context of a template in a route is its controller, not its route. Try moving the action to the controller.

See updated twiddle: https://ember-twiddle.com/b454e10355ae8c708c3b8dc24b51e44e?openFiles=controllers.my-route.js%2C

For more information about controllers: https://guides.emberjs.com/v2.16.0/controllers/

Upvotes: 2

Related Questions