# Route handling multiple complex components

**URL:** <https://discuss.emberjs.com/t/route-handling-multiple-complex-components/19158>\
**Category:** Design\
**Created:** [October 1, 2021, 4:32pm UTC](https://discuss.emberjs.com/t/route-handling-multiple-complex-components/19158 "2021-10-01T16:32:41Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![bsylvain](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/bsylvain/32/16348_2.png) [@bsylvain](https://discuss.emberjs.com/u/bsylvain)\
**Post date:** [October 1, 2021, 4:32pm UTC](https://discuss.emberjs.com/t/route-handling-multiple-complex-components/19158/1 "2021-10-01T16:32:41Z")

</div>

In apps you often have to handle complex routes that interact with multiple endpoints, and I suspect the way I do it is not optimal.

The use case I am talking about is when you have multiple components with inputs that will each display a data collection that is dynamic (pagination, search, etc…)

I handle it by definning the componnents params in the route’s model

```auto
  model() {
    const user=this.modelFor('users.edit').user
    return hash({
      user: user,
      paidParams: {'state': 'paids','user_id': user.id,},
      progressParams: {'state': 'progress','user_id':user.id},
      messages: {'user_id':user.id}
    });
  },

```

I pass each params to each component. In the component I define a loading function that is called in init() and also each time an input is made (here it’s pagination)

```auto
import Component from '@ember/component';
import { inject as service } from "@ember/service"

export default Component.extend({
  init(){
    this._super(...arguments);
    this.set('queryParams',Object.assign(this.get('queryParams'),{page:{number: 1,size: 5}}))
    this.get('loading')(this)
  },
  drawConsole: (function(){}),
  collection:null,
  queryParams:{},
  loading(parentThis){
    parentThis.set('isLoading',true)
    let queryParams=parentThis.get('queryParams')
    parentThis.set('collection',parentThis.get('store').query('invoice',queryParams)).then(
      ()=>{
        parentThis.set('isLoading',false)
      }
    );
  },
  store: service(),
  actions:{
    refreshData(page){
      let params = this.get('queryParams')
      params.page=Object.assign(params.page,{number: page})
      this.set('queryParams',params)
      this.get('loading')(this)
    }
  }
});

```

It works very well, but I never saw anyone use a JS function in an ember object, and It seems that access to the store for this type of data should be in the route itself.

---

<div class="post-metadata">

**Author:** ![ef4](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/ef4/32/13470_2.png) [@ef4](https://discuss.emberjs.com/u/ef4)\
**Post date:** [October 2, 2021, 9:11am UTC](https://discuss.emberjs.com/t/route-handling-multiple-complex-components/19158/2 "2021-10-02T09:11:53Z")

</div>

For your use case, I think it makes sense to load data from the components, but I would suggest making the data loading functions into ember-concurrency tasks. Otherwise there are many concurrency bugs you’d have to solve manually. For example, the `loading()` method above:

1. Is not cancelled if the component is torn down before the query finishes, which will result in an exception when `set('isLoading', false)` tries to run on a destroyed component.
2. Allows multiple queries to race each other, if the input parameters change while a query is still running. The newest query doesn’t necessarily win, the fastest wins, and that could show inconsistent results.
3. Gets stuck forever in the loading state if the query encounters a network error.

More detail on the general question of when and how to load data in the router vs components is here: This is relevant to your question:

> [@Readers' Questions - "Is it bad to load data in components?"](https://discuss.emberjs.com/t/readers-questions-is-it-bad-to-load-data-in-components/14521):
>
> Hello once again to Readers’ Questions, presented by the Ember.js Times. Today I’m answering this question by jj: Is it still considered an anti-pattern to handle lots of data loading in the scope of Components? In general, it’s not an anti-pattern to load data in a component. But there are two common ways people go wrong by loading data in components: They load data in a component when the router could have easily done it for them (thus spending effort and increasing complexity for no be…

Finally, I will point out that there’s no need to do this:

```js
this.get('loading')(this)

```

You can invoke your own methods normally on Ember Component:

`this.loading()`.

(Or use a Glimmer Component, which doesn’t extends from Ember.Object at all and has none of the special `get`, `set`, `extend` stuff that is causing this confusion.)
