How To Use Return Value from Controller in Route? {{SOLVED}}


#1

I have this controller (controllers/movies.js):

import Ember from 'ember';

export default Ember.Controller.extend({
  queryParams: ['t'],
  actions: {
    findMovie() {
      let value = this.get('value');
      return this.get('store').queryRecord('movie', {
        t: value,
       r: 'json'
      });
    }
  }
});

…that is triggered by the click event on a button. It is triggered just fine, and I can see the data being retrieved in my browser’s inspector. So-- in my route (routes/movies.js), how do I access the data returned by the controller?

import Ember from 'ember';

export default Ember.Route.extend({
  model() {

  }
})

I’ve just started learning Ember, and originally I had my store query in the route with the ‘t’ parameter hard-coded, and it worked fine. But now that I’ve moved the query logic into a controller, I have no idea how to pass the resulting JSON back to my route’s ‘model()’ method…

Thanks! Bryan


#2

Hey Bryan,

Typically a good rule of thumb is to keep as much of your data fetching as possible in your route’s model. The router has been carefully designed to handle async logic and it can save you a lot of trouble to try and keep as many of your async requests as possible in the model hook.

So for your problem what I would do is probably use query params to reload the model when the query changes. Basically, your action would set a property on your controller which would be wired up as a query param (you already have one, ‘t’). Let’s say you call it “search”. So in your action you do a this.set('search', value), and add ‘search’ to your queryParams array.

Then in your route:

import Ember from 'ember';

export default Ember.Route.extend({
  queryParams: {
    search: {
      refreshModel: true
    }
  },

  model(params) {
    return this.get('store').query('movie', {t:params.search, r:"json"});
  }
});

Then anytime the “search” query param is changed (e.g. when your action fires and sets that prop on your controller) it will refresh the route model. Then you can keep your data fetching in the route model hook which is the goal. Hope that helps!

See the query params guide for more details: https://guides.emberjs.com/v2.14.0/routing/query-params/


#3

This sounds great! I was hoping to keep everything in my route, but couldn’t find exactly what I was looking for in the docs/tutorials; they always showed how to return hard-coded data, or do a ‘findAll’ that doesn’t require a parameter to be passed to the query.

I’ll give this a go!

Thanks, Bryan


#4

Yeah a lot of the docs are narrowly focused on the topic at hand, which makes sense, but it makes it hard when you’re looking for examples of several concepts being combined. Good luck!


#5

Working like a champ! So in order to possibly assist others, here’s my final controller and route code:

Controller:

import Ember from 'ember';

export default Ember.Controller.extend({
  actions: {
    findMovie() {
     this.set('search', this.get('value'));
    }
  }
})

Route:

import Ember from 'ember';

export default Ember.Route.extend({
  queryParams: {
    search: {
      refreshModel: true
    }
  },
  model(params) {
    return this.get('store').queryRecord('movie', {
      t: params.search,
      r: 'json'
    });
  }
});

And to further clarify: I’m calling an API that expects a parameter ‘t’ to be passed (title of the movie you’re searching for), and ‘r’ for the type of data to return.

Big thanks to dknutsen for saving my sanity. :slight_smile:

Bryan


Ember data findRecord return value is not the expected record