Help understanding interaction between controller and model and route

I have an app where the controller has an action which makes a HTTP request and I want to get the json payload and use it in my template of the same name. I think I am meant to use setupcontroller and set the payload to the model. Do I use setupcontroller inside my controller? Or am I meant to create a route for this? Could someone help explain how these would all interact together. Much appreciated

Hi @alyssa21, welcome! Here are the broad strokes:

  • Route: a route typically encapsulates data fetching, and is also responsible for mapping an app path/url to a specific template. Usually you set up a route in your router with the “path” that you want, and any path parameters (dynamic segments) and then the route will define what data is fetched to populate that template
  • (Route) Template: defines the DOM matter and components that will be rendered for the matching route
  • Controller: holds view-level state that should be exposed to the route template. Typically the route fetches a model and passes it to the controller for the template to consume (more on that below).

Data can be fetched outside of a route, for example in a controller or a component, but in general you don’t want to do this unless you know what you’re doing. Mostly because routes encapsulate asynchronous data fetching very nicely and take care of a lot of the hard parts of that (error handling, loading state, blocking render until data is present, etc) for you.

Another thing to know is that, by default, a route implements a setupController hook that sets the result of the model hook on the controller for you as model. You don’t need to do this manually unless you really want to.

Could you describe your controller a little more, and the HTTP request it’s making? It might be a good idea to refactor it to fetch that data in the model hook of the route. If not you may want to encapsulate it in a better way.

Thanks for that!

I dont think I want to map my app templates to be mapped to a specific path so I think I will continue with fetching data inside my controller.

Sure, my application.js controller is very simple and has actions for when a button is pressed, such as making this POST request using async. I grab the response data in a variable using await response.json() but then I am stuck in going about passing this json payload to my template of the same name. Using setupController in a route is the only way of making this work?

I dont think I want to map my app templates to be mapped to a specific path so I think I will continue with fetching data inside my controller.

A controller is inherently coupled to a route so technically your application controller is still going to be coupled to the “root” route, but yes. Makes sense.

making this POST request using async. I grab the response data in a variable using await response.json() but then I am stuck in going about passing this json payload to my template of the same name. Using setupController in a route is the only way of making this work?

Yeah a POST is something you usually do in a controller or component so that makes more sense. All you need to do from a controller to set something on the controller is this.set('propNameHere', stuff) in classic Ember or in Octane you should just be able to do this.propNameHere = stuff;. The controller has “access” to anything declared on the component class, so in the template this data would then be accessible by {{this.propNameHere}} or {{#each this.propNameHere as |item|}} etc.

1 Like