Search queries - dynamically reloading model

Hi,

I have another conceptual question which is not really covered in the documentation. Or maybe it is just me not finding it or simply not understanding something.

The use case is actually exactly what we find covered in the getting-started tutorial: Ember Data - Part 2 - Ember Guides

Let’s keep the terms of this (very nice) tutorial. So we have a rentals homepage and want the user to be able to search for some specific places. This is solved in the tutorial by loading the data in the model hook:

async model() {
    return this.store.findAll('rental');
  }

and when the user enters something in the search bar, we sort all this rentals on the client side to display the ones where the keyword is matching some meta data of a rental .This “findAll” approach is very present throughout documentation and many examples.

This approach is ok for a tutorial, but imho it will not scale for a lot of real life use cases. Imagine we have 10000 rental entries in the database, we do not want to fetch all of them at first and then start looking for the 3 the user actually asked for on the client side. Instead we want only those 3 records to be fetched.

Now I do know how I can make this work in principle, I also digged around and found how the discourse software is doing it. If I am not mistaken they are firing the ajax call for the search in the controller:

And obviously it works. But being exposed to all this “load your data in the route, young padawan” mantra I am asking myself if… well … I can load the data in the model hook of the route somehow. Quite some time has passed since discourse was written and so maybe there is some other way which is more in line with “the ember way”.

The problem of course is that the model hook already fired when the user gets the chance to type anything into the search box. At least when we look at the way it is done in the getting-started tutorial. So we can not add the keyword the user typed into the store search query.

Is there something in the documentation I am missing that covers this aspect? In this case a link would be much appreciated.

If not, can someone with more ember experience explain how this can be done using ember-data and the model hook? Somehow with nested routes which we can call again when the user finished typing (without rerendering the whole page/parent template)? Ideally it would use query parameters, so users could bookmark search results. Here I am not sure how I am supposed to put the query-parameters in the store query in a sane way.

I feel like ember could benefit from a refined+documented way to do this kind of stuff (… if this is not already covered in the documentation of course).

Thanks!

There is a small example of this in the guides in the Query Params section, specifically opting into a full transition. At a high level the steps involved are:

  • add a query param to your controller to bind the controller property to your query param in the URL
  • add the query param(s) to the route with refreshModel: true to essentially re-fire the model hook when the query param value changes
  • consume the query param in the model hook by passing params to store.query

Then if you set the prop on your controller the model hook will refire.

If you want to reduce how often this happens (like when typing in a search box) there are a couple things you could do, but the gist is “don’t set the controller property until you’re ready” for the model hook to reload. This could mean debouncing the input so it doesn’t set the prop until some time delay, or it could mean using a search/button combo where you type in the search box and the click a button to do the actual search.

I feel like ember could benefit from a refined+documented way to do this kind of stuff (… if this is not already covered in the documentation of course).

I totally agree, and I think we all do. Unfortunately there’s a tough balance to strike in tutorial documentation between simple and too verbose, and it’s hard to maintain more “robust” example/best practice documentation. In fact there was a recent discussion of just that topic in this very discourse board:

1 Like

As a follow-up I’ll note there’s nothing wrong with loading data in components either. The guides push pretty hard on route-based data loading, and while this is the easiest way to do it (Ember takes care of all the complexity for you) and probably want you want in the majority of cases, it’s certainly not required and it’s not “bad practice” to load data in components instead of a route model. It’s just hard to establish good patterns of doing it right and not missing key details. At my company we load the majority of our data in components for a number of reasons. We’ve built up some good primitives for dealing with this though.

If you’re curious about the topic one thing that will make data loading in components more straightforward is the @use and Resources RFC (or whatever it ends up being), currently implemented experimentally in userland as ember-could-get-used-to-this.

1 Like

Hi dknutsen,

man, thanks a lot! This is exactly the piece of information I needed. Yeah, documentation is a tough topic. Besides having good documentation it is an art in itself to make it accessible for the user, making sure people find what they are actually looking for.

To find the information in the plain explanation of concepts is hard, because in a lot of cases this is not how a lot of people look for it. You start by searching for your exact problem, which in some cases already helps but often leads you nowhere. From here you start generalising your search keywords, one bit at a time.

And here you have to be very lucky to hit exactly the wording which is used in precise, plain explanation of concepts, because those tend to use specific terms which are often exactly the piece of information the user does not have.

My only idea is to still have one generic explanation of a concept, to keep the maintenance overhead as low as possible, but put easy to look for examples in the “abstract”. Common use cases (in different wordings) where the given concept/feature is the way to tackle the problems involved. So the chances for people to hit the keywords of the documentation are much higher. I know this is much easier said than done. Just my 2cents.

Thanks a lot for the RFC, I will most definitely have a look.

Another thing you can search for is Ember Concurrency. It’s not quite as modern as Octane so it has a few things that don’t feel as nice, but it handles the denouncing aspect of things quite nicely