Making The Model Hook Not Block Rendering

The Ember Router is pretty great, but it does have some limitations in waiting for promises to settle before rendering. For instance if you have network call is taking a long time what you really want to do is not block the rendering of the UI. Instead you want to take advantage of things like ArrayProxy, ObjectProxy, and the PromiseProxyMixin and let them resolve when they are already placed on the controller. See example. This allows you to give users immediate feedback and it also allows you to render content not dependent on the request e.g. static strings.

What I’m proposing is that there is some API that I can call similar to what I’m doing here, that allows for non-blocking rendering at the same time placing the proxied object onto the controller.

1 Like

why not just not use the model hook for this purpose, rather use setupController?

I suppose if you want nested routes to work as expected you want to use a non-thenable in the model hook. Something like a promise proxy without a then on it could be used.

This will still give you all the helpful bindable flags like isPending isRejected, but wouldn’t pause routing.

1 Like

Yea so if you wrap the PromiseArrayProxy in an ArrayProxy you can get the nested routes to work. There seems like there should be a less manual way of doing this is what I’m getting at. :smile:. The other option is just implement my own Adapter.

Ya some defacto sanctioned way seems legit.

For this type of progressive model loading I just approach it like this, which to me is a conceptually simpler way of thinking about it

@alexdiliberto I need this to be the default behavior because I’m a SOA where certain calls can be more expensive than others. Asking every developer to make sure they wrap their fetches in a proxying object is sort of a no go.

I ended up extending the DS.Store so it doesn’t return a promiseArray or promiseObject, but rather a plain recordArray or a model instance. We’re currently opting into this progressive rendering on the initial load, any subsequent requests pass back promiseArray or promiseObject. The reason for this is that we are streaming/multiplexing the models to the base page and just pushing the payloads into the store.

This something we’re still playing around with to get sub 1sec user feedback.

1 Like

Any word on a “sanctioned” way.

I thought to the same like @chadhietala but it does not always work as simple. E.g. if the list is empty and you want to display a message like “Empty list” then during the findAll request, the empty list message will pop and a few ms later replaced by the loaded list…