So, I am building a map using angular and leaflet. One of the things that I use is leaflet.markercluster. When i click on the cluster I want the popup content of a random marker of a cluster to be written somewhere. To access the popup content of some random cluster I did this:
cluster.getAllChildMarkers()[0]._popup._content
and got an error: Property '_popup' does not exist on type 'Marker'.
But the thing is, if I do ng serve first time it failes to compile, but if I change anything and save all it compiles sucessfully with the errors and I can see the content of the popup.
Also, if I do console.log(cluster.getAllChildMarkers()[0]) and I inspect element on webpage I get the regular console log of a marker with latlng andall other atributtes, including _popup.
Does anybody know why does typescript/vscode log an error, but html console sees it normally?
Because TypeScript is more strict than JavaScript, it warns you of potential issues that may actually work just fine once transpiled in JS.
In this specific case, this is simply due to the pseudo private properties ("_popup" follows the usual JS libraries convention of using an underscore _ prefix to denote pseudo private members) not being declared on the TS types of Leaflet, since you are not expected to use them.
But of course this is still technically valid in JS, so you can tell the TS compiler "I know what I am doing" by using the //#ts-ignore comment directive just above that line.
Or longer but much better, since you can remain under TS watch: use actual Leaflet API to achieve what you are doing:
getPopup() method
getContent() method
cluster.getAllChildMarkers()[0].getPopup()?.getContent()
Is it possible to navigate to in-page URL fragment subresources with react-native-render-html as implementing browser behavior? Here is an example. Given this snippet for the html prop:
<h1 id="title">The Title</h1>
<div style="width:50px;height:200px;">
...
</div>
Scroll to The Title
When a user presses the "Scroll to The Title" anchor, I would like to contain ScrollView to scroll to "The Title" header.
Linking.openURL is not working can you suggest me the way?
Implementing this feature is very specific to the underlying HTML structure, so there is not an absolute, generic answer. That is why this feature will not be provided by this library. However, there is a good step by step guide in this tutorial I wrote for V6.
I'll summarize the important steps below:
Thanks to custom renderers, we can map the coordinates of each target with their id in a cache object (Scroller in the above tutorial) by using onLayout prop. Beware that those coordinates are relative to the parent View.
In the same cache object, we store a reference to the underlying ScrollView.
We define a scrollToId method in the cache object, which invokes the underlying ScrollView ref scrollTo method to scroll to the coordinates we previously mapped to the target.
We set the renderersProps.a.onPress prop to a callback which will invoke the scrollToId method of the cache object.
Note that you'll need to pass the cache object to the custom renderer via a context or via renderersProps (you can then consume the prop with useRendererProp).
Those steps are freely adapted from the above tutorial and I invite you to dive in to grasp all the implementation details. Good knowledge of React hooks, context and refs is required.
Known feature:
<div #element (click)="myMethod(element)"></div>
this passes the div back to the VM for manipulation, etc.
What I'm looking for is short hand to pass an element to a method without declaring a template variable. It could look like this:
<div (click)="myMethod($self)"></div>
This would be helpful in cases where creating elements in an ngFor stops you from giving every element a variable name or in cases where using a third party library that sends its own $event and the element ref is missing. Does anyone know of any way to do this?
Lots of new functions released with React 16. One of them is the ReactDOM.createPortal(child, container) API, which is handy for visually breaking out of its container.
However, it seems like that it not only breaks out its container but also breaks the basic html rules which I learned from the first day of web development. The createPortal API let you render your component out of its parent, and break the html structure convention we expected.
In the other hand, we do retrieve more flexibility and now can render DOM in the sibling or else components.
IMO, I don't think this is a good deal to gain more flexibility by trading html convention in. Also the example supplied by official does not convince me.
What I am curious about is:
Is there anyone who face any condition that createPortal API is a must?
thanks
The examples in the docs are some of the cases where createPortal is really useful - specifically dialogs, hovercards, and tooltips.
The docs also specifically state:
Note:
It is important to remember, when working with portals, you’ll need to make sure to follow the proper accessibility guidelines.
As an example, the docs show how a modal could be built using createPortal(). You'll notice the modal is created in the #modal-root element, which is a root element alongside the #app-root element. This is a great example of how createPortal() can be used without violating any HTML rules.
<div id="app-root"></div>
<div id="modal-root"></div>
I ran into another use case a few months ago. Because React 16 portals were not available, I had to use a home-baked portal implementation.
I was creating SVG graphs. All of the lines, paths, and so forth needed to be rendered inside an <svg> element. But I wanted to use HTML to render text labels (for a number of reasons). This meant that an object on the graph and its label would necessarily be in separate parts of the DOM. But with portals, I could still keep all of a graph component's logic together. Here's a fictitious example:
const LabeledPoint = ({ x, y, r, labelText }) => [
<circle cx={x} cy={y} r={r} />,
<GraphLabel x={x + 5} y={y}>{labelText}</GraphLabel>,
];
You would use this component inside an <svg> element. The GraphLabel component would use a portal to render labelText in an HTML div element at the same coordinates as that <svg>, using absolute positioning to place it at the correct coordinates.
This way, all of the logic for a single component could be in one place even if I needed to render the actual DOM elements in different places for technical reasons.
Portals is very useful feature when you need to render your component outside the DOM hierarchy of the parent component.
You define a portal using the following syntax:
ReactDOM.createPortal(child, container)
The first argument (child) is any renderable React child, such as an
element, string, or fragment. The second argument (container) is a DOM
element.
See the following tutorial to see how and why to use portals:
https://www.youtube.com/watch?v=lOMU9BeIrO4
Before going into my answer, I'll just note that I interpret the question as "in which cases is there no alternative to using a portal, or a portal would be a demonstrably much better solution?"
There are very few cases where portals are the only solution. A lot of the time there's a way to structure your app so that you don't need to use them. There's some niche use cases, but even there it's usually not the only solution.
For example in the SVG use case, you could instead create a Labels component that takes an SVG React element as argument, and then loops recursively over the children to construct an HTML element with matching labels in the right position. That would as a bonus also make the SVG code a lot simpler. If the SVG is user editable, you'd have to store its state as a whole anyway on each change, allowing you to easily pass the state back into both SVG and label elements. That said, here the portal solution seems at least on par with the alternatives, and could be the simplest in some circumstances.
Dispatching plugin components
Portals can be useful for library/framework authors. It allows plugins to render multiple components in the same element, each of which the framework then portals to a different position in the UI (e.g. editor area, sidebar).
WordPress's block editor uses this for a few things, they call it SlotFill. For example if you're coding a new block in a plugin. You always provide an edit component for each block, which is rendered to the WYSIWYG editor. If it includes an InspectorControls component, everything inside it will go into the sidebar.
The Block Toolbar works in the same way. Content of the <BlockControls/> element is moved to the toolbar that is displayed right above the block content.
This is implemented as a portal to a registered slot.
The advantage of a portal here is that it allows a block's code to reuse the state and hooks in all components, even though they are not rendered in the same place. This makes the process of adding sidebar code very easy and with minimal repetition. If plugins instead needed to provide each of these components as a standalone React component, managing their state would be much more complex.
Example
You won't find ReactDOM.createPortal in the example itself. It's rather an example of how a plugin can benefit from a framework that uses it. See WordPress's source code if you're interested in the implementation details.
I added a simple useState hook to the mentioned InspectorControls example and removed some irrelevant parts.
edit: ( { attributes, setAttributes } ) => {
const [myColor, setMyColor] = useState('#fff');
return (
<div>
<InspectorControls key="setting">
// Simplified HTML, real world blocks use more complex HTML here.
<ColorPalette
value={myColor}
onChange={ setMyColor}
/>
</InspectorControls>
<TextControl
value={ attributes.message }
onChange={ ( val ) => setAttributes( { message: val } ) }
style={ {
backgroundColor: myColor,
color: attributes.text_color,
} }
/>
</div>
);
},
What is the correct way to implement internal linking in Polymer 2.0 (linking within the same page)? I cannot seem to get access to my components that are buried within ShadowDoms, so the traditional way of using link to top and <a name="my_section"></a> and <a id="my_section"></a> does not work.
I have also tried the solutions here to no avail:
How to query elements within shadow DOM from outside in Dart?
Is it possible to access Shadow DOM elements through the parent document?
Using querySelector to find nested elements inside a Polymer template returns null
The following code that I've tried all return null, even when I add an id to my component:
document.querySelector('#my_section'); //null
this.$.my_section; //null
this.root.querySelector('#my_section'); //null
this.shadowRoot.querySelector('#my_section'); //null
Perhaps there is a way to accomplish this using <app-route>?
I'm quite new to Polymer so any advice would be appreciated. Thanks in advance.
Please share more detailed code that which elements you want to access and manuplate. Here at this document
https://www.polymer-project.org/2.0/docs/devguide/dom-template
under the Static node map head shows shortly :
The this.$ hash is created when the shadow DOM is initialized. In the
ready callback, you must call super.ready() before accessing this.$.