Mithril.js: Make `background: true` be the default for `m.request`

Created on 28 Aug 2018  路  8Comments  路  Source: MithrilJS/mithril.js

Considering how (not) often it is you want to request data and immediately re-render, it'd make more sense to just background everything by default and require an explicit background: false to force a re-render. If this turns out successful, we might want to consider removing the option altogether in the future (post-v2). We're kind of the exception in trying to provide some sort of autoredraw mechanism from network requests, and it's not like they couldn't drop a .then(m.redraw, m.redraw) at the end if necessary.

Breaking Change

Most helpful comment

Me and Isiah chatted about this on Gitter. The proposal isn't a feature, it's a design proposal that would allow Mithril's constituent modules to be separated by default such that the renderer & request modules could be imported individually. Auto redraw could then be reimplemented as a wrapper.

All 8 comments

I find the a redraw required after 90% of my http requests. I prefer to keep the flag for the less-common option.
Consider your usage, how more often then not do you @isiahmeadows not require a redraw?

I've never been hurt by the extra redraw, and I have relied on it unconsciously multiple times.

I almost always wrap m.request anyway, so I would find it fairly simple to disable the functionality generally in a project if needed (I haven't had that need yet).

Just a bit of anecdata from here ;)

@yossicadaner Usually, I do require an eventual redraw, but it's usually something where an explicit redraw is better. If you need to do request multiple things or if it's a more complex request, you'll have to do an explicit redraw either way, so the extra redraw is wasted.

There's also a little bit of philosophy, where I noted in Gitter that removing the autoredraw behavior would fully decouple the request utility from the rendering. (That'd make it easier to test and more usable server-side, assuming an XHR mock.)

Me and Isiah chatted about this on Gitter. The proposal isn't a feature, it's a design proposal that would allow Mithril's constituent modules to be separated by default such that the renderer & request modules could be imported individually. Auto redraw could then be reimplemented as a wrapper.

Ah, for some reason I had the idea mithril returned a special promise that would hold the redraw until the end of the promise chain. Just tested, and I see that's not the case, so I'm actually fine with background being removed and just having it in a wrapper if necessary.

Maybe I remember that end of chain thing from back when m.request returned a stream?

@porsager Leo and Pat did work at that in the initial rewrite. The problem with that proposal was that it misunderstands the nature of Promise chains: you can't determine where they end; promise chains can be infinitely recursive.

Discussion here.

@porsager You're probably remembering from v0.2, where you'd see some very subtle behavior that looks like that:

  • m.deferred's .then callbacks were synchronously invoked.
  • m.deferred returned this really weird magic m.prop-like object that was somewhere between a prop and a promise, kind of both, kind of neither.
  • m.request scheduled a re-render using setTimeout

Thanks to a fully synchronous pipeline and it waiting until the whole pipeline finishes for most calls, it was pretty easy to be a bit magical about it and still get away with it for the most part. (The few glitches are precisely why background: true existed, but it wasn't there from day 1 IIRC.) Back then, it was still pretty easy to use, even with the async pipeline, since:

  • value: ctrl.value(), oninput: m.withAttr("value", ctrl.value) was a very common idiom, and is precisely why I've been pushing a little to bring that back into the core bundle.
  • m.request returning a m.prop-like instance made it interact very nicely with the above - you could fetch a resource with an initialValue: ..., and use that within the view for a very nice and easy fetch-and-two-way-bind combo without much effort.

But with v1+ returning an actual promise, the sync/async timing schizophrenia around m.redraw (fixed in v2), and the fact the chain recursively overrides .then for all its magic semantics instead (it doesn't even do that correctly - try returning a primitive like undefined), I'm surprised nobody has reported issues with it yet.

Ah yes, that's what I was thinking of @barneycarroll ;)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mikejav picture mikejav  路  3Comments

josephys picture josephys  路  4Comments

barneycarroll picture barneycarroll  路  3Comments

volnei picture volnei  路  3Comments

isiahmeadows picture isiahmeadows  路  4Comments