Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve layer load #623

Merged
merged 14 commits into from
Jul 4, 2018
Merged

Improve layer load #623

merged 14 commits into from
Jul 4, 2018

Conversation

elenatorro
Copy link
Contributor

@elenatorro elenatorro commented Jun 26, 2018

Related with #604
Related closed bugfix: bef7482


Current solution

We have two ways to handle this issue.

  1. Use try catch to handle mapbox error when style is not loaded. We listen to map.on('load') to add the layer if the error has been triggered.

  2. Check map.style._loaded.
    If this property is false, then we listen to map.on('load') to add the layer.

Both of them have been tested and they work, but we have chosen the first one because the second one depends on a private variable that may change.


Previous research:

We can not relay on map.isStyleLoaded() to safely add a layer.

There is an interesting Mapbox issue thread where this problem is being discussed. Highlights:

load and styledata are fired when the style initially loads, but then never again - even though isLoaded() and isStyleLoaded() are reporting false as the camera zooms in.

.loaded() is basically not useful for determining whether one can safely add a layer, and the user is responsible for adding a .once("load", () => map.reallyLoaded = true listener in order to be able to safely add layers later.

Another problem is that when trying to add a layer, mapbox-gl throws an error if the styles are not loaded. That is why we need to check somehow that the styles have been loaded. Since there is not a safe way to do this check, we would probably have to change our fork.

@elenatorro elenatorro requested a review from IagoLast June 26, 2018 15:28
};

const mapMock = {
isStyleLoaded: () => true,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jasmine.createSpy('isStyleLoaded').and.returnValue(true); 🙄

@elenatorro elenatorro changed the title Improve layer load [WIP] Improve layer load Jun 27, 2018
src/api/layer.js Outdated
map.on('load', () => {
this._onMapLoaded(map, beforeLayerID);
});
map.once('data', (event) => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why does this work? Does it work? I thought that MGL required the style to be loaded before the addLayer method works

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MGL requires the style to be loaded if the data event type is sytle. About the data event, after reading the documentation I think it is the only change that needs to be listened, and only the first time (that is why I am using once).

https://www.mapbox.com/mapbox-gl-js/api/#map.event:data

Fired when any map data loads or changes

The examples in the editor work, but I agree it needs further testing.

});

it('should call onMapLoaded when the map `load` event is triggered', () => {
describe('and dataType is style', () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when datatype is style ?

src/api/layer.js Outdated
this._isSourceLoaded = false;

map.on('sourcedata', this._onMapSourcedata);
map.on('load', this._onMapLoad.bind(this, map, beforeLayerID));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think

map.on('load', this._onMapLoad.bind(this));

is more intuitive since we only bound the context but the parameters

src/api/layer.js Outdated
if (map.isStyleLoaded()) {
this._isSourceLoaded = false;

map.on('sourcedata', this._onMapSourcedata);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dont we need to bind this here?

src/api/layer.js Outdated
}

_onMapLoad(map, beforeLayerID) {
if (map.isStyleLoaded() || this._isSourceLoaded) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this._isSourceLoaded is always undefined because this (pun intended) :trollface:

@rochoa rochoa mentioned this pull request Jul 2, 2018
src/Layer.js Outdated
this._onMapLoaded(map, beforeLayerID);
} else {
} catch (error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since multiple errors could happen here I'd look for the specific mapbox error and act accordingly

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with that, but I am not sure how to check it since error is a string and the message may vary also. This is how the error is triggered

    _checkLoaded() {
        if (!this._loaded) {
            throw new Error('Style is not done loading');
        }
    }

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

catch(err) {
// We can control the situation when the error is "style not done loading"
  if(err.message === 'Style is not done loading') {
    this._onMapLoaded(map, beforeLayerID);
    return;
  }

// Otherwise a "real" error happened, forward it
throw error;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done :)

Copy link

@davidmanzanares davidmanzanares left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀

Copy link
Contributor

@IagoLast IagoLast left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@elenatorro elenatorro merged commit f18b74a into master Jul 4, 2018
@elenatorro elenatorro deleted the 604-improve-layer-load branch July 4, 2018 09:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants