dasmoth / dalliance

Interactive web-based genome browser.
http://www.biodalliance.org/
BSD 2-Clause "Simplified" License
226 stars 68 forks source link

callback for stylesheet loaded #157

Closed Traksewt closed 9 years ago

Traksewt commented 9 years ago

Currently I can add a tier, and that will call Tier.init(), which may retrieve a remote stylesheet. In my case, I add some tiers, then want to call retrieve Tier Data on it and then render it. However, by the time it is calling Kspace.startFetchesFor, the stylesheet may not be downloaded, which cases an early exit.

if (styleFilters)
    wantedTypes = styleFilters.typeList();

... if (wantedTypes === undefined) { return false; }

Is there any way we can make this wait for stylesheet to be retrieved first?

Another option is to abstract the creation of the Tier to the rendering of it, similar to how we did abstracted the tier data retrieval to its rendering. At the moment, the tier creation ends up calling: tier.browser.refreshTier(tier);

This can be changed to adding a callback.

I could do this by changing: Browser.prototype.addTier = function(conf) { to Browser.prototype.addTier = function(conf, callback) { where the callback is optional, and it will default to the default refresh renderer.

If I get a callback on adding Tiers (when the stylesheet is loaded), then I can manage when to call to retrieve the data.

Let me know if you have any other ideas.

dasmoth commented 9 years ago

The reason we've got this somewhat-nasty state machine is that some back ends have the ability to filter features e.g. by type (primarily DAS, but there are other uses for this stuff as well), so it's important to get the stylesheet before initiating any fetches.

What I'd ideally like to see would be "headless tiers" (along the lines of what we've discussed previously) implemented with their own class(es), which can fetch stylesheets or not as they choose (I guess with the stylesheet-fetching code factored out a bit). That's probably not something to rush, though.

A quick solution might be, when creating dummy tiers to support your feature fetches, to bypass the stylesheet fetching process entirely. The easy way to do this would be to include a minimal JSON stylesheet within the tier configuration, e.g.:

     b.addTier({
           name: 'dummy',
           bwgURI: '/foo.bw',
           style: [{type: 'default, style: {glyph: 'BOX'}}]
    });

This should be installed during tier creation without any async shenanigans, and you're ready to go.

If this doesn't work for you then certainly go ahead and add the callback to notify when the tier is ready, but do mark it as a temporary thing, since it seems like it's making the async problems worse, not better.

dasmoth commented 9 years ago

Actually, rather than taking a callback when creating a tier, why not return a Promise instead (which will yield the newly-constructed Tier once it's ready)?

Traksewt commented 9 years ago

OK great, I'm actually using promises already in my code (for the callback in my fix) anyway to determine when the tier stylesheets have been loaded. So I'll move the promise to Dalliance instead. I guess something like this will be needed even when the tier is headless, if the backend can filter by features. Thanks.

Traksewt commented 9 years ago

Just clarifying that this change will be 'api' breaking. Currently Browser.prototype.addTier returns a Tier object. I'll make it return a Promise that resolves the new tier (once stylesheet is loaded).