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

marker addTo ->ERROR TypeError: this._offset.mult is not a function #13145

Open
simplelayers opened this issue Apr 12, 2024 · 4 comments
Open

Comments

@simplelayers
Copy link

simplelayers commented Apr 12, 2024

For a line of code that worked in version 2.* which is attempting to add a Marker to the map using addTo
"this.queryMarker.addTo(this.map.ui);"
where this.queryMarker is a Marker
and this.map.ui is a mapbox-gl Map instance

I am getting an error:
ERROR TypeError: this._offset.mult is not a function
at aI._updateDOM (mapbox-gl.js:33:808684)
at mapbox-gl.js:33:810271
at Map._requestDomTask (mapbox-gl.js:33:843059)
at aI._update (mapbox-gl.js:33:810216)
at aI.addTo (mapbox-gl.js:33:805410)

mapbox-gl-js version:
3.*
2.14.0
Seems to happen after version 2.7.0 where the addTo command worked.
browser:
Chrome

Steps to Trigger Behavior

I have not confirmed the error in a simpler setup, but the line of code shared above has worked for a couple years and suddenly isn't.

Link to Demonstration

not presently possible
I appreciate the virtue of having a discrete test setup.
However, the offending code exists once and should be easy for an IDE to find, just look for this._offset._mult
"_updateDOM(){const e=this._pos;if(!e||!this._map)return;const t=this._offset.mult(this._scale); ..."

What reasons would this._offset be null/undefined? or not have the expected mult function?

Expected Behavior

I expect a marker to be added to the map without error

Actual Behavior

I get an error about this._mult not being a function.

@mourner
Copy link
Member

mourner commented Apr 12, 2024

What reasons would this._offset be null/undefined? or not have the expected mult function?

It's impossible to tell without knowing more about your codebase or having a reproducible example. Does the marker call setOffset at any point, possibly passing a nullish value?

@simplelayers
Copy link
Author

simplelayers commented Apr 12, 2024 via email

@simplelayers
Copy link
Author

simplelayers commented Apr 13, 2024

I found the issue:

version 2.7 marker.js:

_updateDOM() {
        const pos = this._pos || new Point(0, 0);
        const pitch = this._calculatePitch();
        const rotation  = this._calculateRotation();
        this._element.style.transform = `${anchorTranslate[this._anchor]} translate(${pos.x}px, ${pos.y}px) rotateX(${pitch}deg) rotateZ(${rotation}deg)`;
    }

Note:
const pos = this._pos || new Point(0, 0);

It is establishing a new point if one is not set

However, that is not happening in the newer versions hence the problem
version 3.3.0

  _updateDOM() {
        const pos = this._pos;
        const map = this._map;
        if (!pos || !map) { return; }

        const offset = this._offset.mult(this._scale);

        this._element.style.transform = `
            translate(${pos.x}px,${pos.y}px)
            ${anchorTranslate[this._anchor]}
            ${this._calculateXYTransform()} ${this._calculateZTransform()}
            translate(${offset.x}px,${offset.y}px)
        `;
    }

My problem is that I need the advancements in 3.* but this is impeding me from being able to upgrade.

@simplelayers
Copy link
Author

I have done a deeper exploration of the issue.
The code adding my marker was:

this.queryMarker = new Marker(
        {
          anchor: 'center',
          element: puc.element,
          draggable: false,
          offset: { x: 0, y: 0 }
        }
      );

For some reason, even though the older versions defined PointLIke as either Point or [number,number] the above worked.
changing offset to new Point(0,0) with the newer versions seems to resolve the error.

In reviewing older and newer versions I don't know that ever should have worked with a non Point object or array.
It appears that the offset option for Parameter is not being checked for being a Point in an {x:number,y:number,z?:number} sense of a Point.

This resulted in _updateDOM seeing this._pos as being an object like {x:0,y:0} and not a Point geometry object with mult as a function.

At this juncture I can only guess that Point.convert recieving {x:0,y:0} used to returned some falsy value.
this._pos didn't get set to a lnglat object or Point object because offset was falsy.
Then _updateDOM used new Point(0,0) because this._pos was falsy and it just so happened that the offset I set at {x:0,y:0} happened to align with the default this._pos new Point(0,0) which worked to initialize the Marker; providing a false positive. When I subsequently set the marker position it moved the marker to where I wanted it so I didn't know there was a problem.

Should there be another aspect of PointLIke that supports a simpler type like

export type PointCoord =  {x:number,y:number,?z:number}

Then Point.convert would need to know to check for Point as a type, an array, or Point Coord and if PointCoord return either a Point or 3DPoint object?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants