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

Bug fix: implement onLoad event calling when reuseMaps is set to true #704

Merged
merged 7 commits into from
Jan 28, 2019

Conversation

hijiangtao
Copy link
Contributor

Description and resolution

According to the discussion in #699 , there's a TODO inside mapbox.js, which is calling onLoad event again when map instance is re-created again with its' property reuseMaps set to true.

However, we need to handle two situations here:

  1. We need to setStyle with customized mapStyle: In this situation, we need to wait until style is loaded, and then call onLoad event handler; we choose .once API here to listen style.load event;
  2. We don't need to setStyle with customized mapStyle: In this situation, we can directly generate an event object and pass it to props.onLoad method and call it right now;

Tests and documentation

  • Test: npm run test passed with 222 tests.
  • Documentation: No need to update document since there's not API change with this commit;

// TODO - need to call onload again, need to track with Promise?
props.onLoad();
// call onload event handler after style fully loaded when style needs update
this._map.once('style.load', props.onLoad);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we know for sure that this event will fire even if props.mapStyle is the same as the last style set?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. We didn't pass the second parameter into .setStyle method (default to false), so we would let mapbox force update even if the style is the same as before, so the event will be fired al the time (in this situation).

Descriptions for options inside .setStyle(style, options)

options.diff: If false, force a 'full' update, removing the current style and building the given one instead of attempting a diff-based update. from https://docs.mapbox.com/mapbox-gl-js/api/#map#setstyle

However, I think there's some other things need to do here:

  1. We don't need to setStyle if current map style is already the things we want (by set options.diff to true);
  2. Because we add step one, so we need to check if the style is fully loaded when we want to manually fire onLoad event (by add isStyleLoaded judgement);
  3. I got a warning of Method '_create' has too many statements (26). Maximum allowed is 25. after I coded the logic above, so I change some code inside the judgement mentioned in step two to a ternary expression;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

One more step didn't mentioned above:

We should listen styledata event rather than style.load event, since later one is a private event inside mapbox, as discussed in mapbox/mapbox-gl-js#7579 (comment) .

@hijiangtao
Copy link
Contributor Author

hijiangtao commented Jan 26, 2019

Actually, there's 5 more things in this new commit, the fifth one is here:

I also unified inputs of props.onLoad event to one object (with type property to be load), though in some situation, the event type maybe styledata rather than load.

That's because developers define onLoadHandler method inside onLoad property of react-ma-p-gl, so they would always want event object that passed to their onLoadHandler should be the same, which should always point to a load event.

It may not be a perfect solution but I think it's the best one right now, a better solution is to have a more precise event types (pretty the same as #683 (comment) ), then we can handler load event and styledata event separately.

A pseudocode should like this inside _create method (suppose there's a handler called styleLoad in props):

      ...

	  // Step3: update style and call onload again
      if (props.mapStyle) {
        this._map.setStyle(props.mapStyle, {
          diff: true
        });

        // call onload event handler after style fully loaded when style needs update
        (this._map.isStyleLoaded() ?
          props.styleLoad() : this._map.once('styledata', props.styleLoad))();
      }

	  props.onLoad({
        type: 'load',
        target: this._map
      });

Copy link
Collaborator

@Pessimistress Pessimistress left a comment

Choose a reason for hiding this comment

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

Looks good to me. Thank you!

});

// call onload event handler after style fully loaded when style needs update
(this._map.isStyleLoaded() ?
Copy link
Collaborator

Choose a reason for hiding this comment

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

This syntax is rather odd. Just use if?

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 got a warning of Method '_create' has too many statements (26). Maximum allowed is 25. if I use if statement, that’s why I choose this one syntax.

Copy link
Collaborator

Choose a reason for hiding this comment

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

You can add this line to the top of this method to disable the lint rule:

/* eslint-disable max-statements */

I will refactor it after the patch.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, that's correct since it will overwrite the global settings. I can handle it by adding another commit.

@Pessimistress
Copy link
Collaborator

BTW you can use examples/reuse-map to test this feature.

@hijiangtao
Copy link
Contributor Author

hijiangtao commented Jan 27, 2019

4 more implements with:

  1. Enrich examples/reuse-map with onLoad event;
  2. Implement TOC since reusemap example had no entrance currently;
  3. Use if statement rather than a ternary expression (and eslint-disable-next-line rather than eslint-disable to control more precise);
  4. Resolve conflicts from upstream;

path: 'heatmap',
name: 'Heatmap',
component: Heatmap
>>>>>>> upstream/master
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry for this, I'll resolve it by adding another commit.

@Pessimistress
Copy link
Collaborator

Reusemap example is not on the website because it does not meet the visual quality bar. Can you remove it for now so that we can release?

@hijiangtao
Copy link
Contributor Author

Removed and by the way, is there any specific guidelines of the visual quality bar (I'm interested)?

@Pessimistress
Copy link
Collaborator

is there any specific guidelines of the visual quality bar (I'm interested)?

Since this is a wrapper library, we try to put up examples that replicate existing mapbox-gl-js examples or at least along the same lines. The reuse-map example in particular was made for performance profiling/debugging purposes so we never bothered to make it look good.

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.

2 participants