Leaflet markers not always applying - node.js

So I'm using leaflet-react and I need to add some circle markers.
Now this code works...sometimes. On map click a circle marker should be added but sometimes it is not. Seemingly randomly it will just not add a visible marker. Sometimes the marker will become visible if I change the zoom level but not always. All the code runs each time so it's not that addMarker() isn't been called, also the removal of the last marker(by clearing the mark layer) always runs.
Thanks, Ed.

It appears that you aren't using the react-leaflet package. I'd recommend trying that out. Here is some example code for how you'd add markers to the map on click events:
const React = window.React;
const { Map, TileLayer, Marker, Popup } = window.ReactLeaflet;
class SimpleExample extends React.Component {
constructor() {
super();
this.state = {
markers: [[51.505, -0.09]]
};
}
addMarker = (e) => {
const {markers} = this.state
markers.push(e.latlng)
this.setState({markers})
}
render() {
return (
<Map
center={[51.505, -0.09]}
onClick={this.addMarker}
zoom={13}
>
<TileLayer
attribution='© OpenStreetMap contributors'
url='http://{s}.tile.osm.org/{z}/{x}/{y}.png'
/>
{this.state.markers.map((position, idx) =>
<Marker key={`marker-${idx}`} position={position}>
<Popup>
<span>A pretty CSS3 popup. <br/> Easily customizable.</span>
</Popup>
</Marker>
)}
</Map>
);
}
}
window.ReactDOM.render(<SimpleExample />,
document.getElementById('container'));
And here's a jsfiddle showing the implementation: https://jsfiddle.net/q2v7t59h/413/

Related

tiptap ReactNodeViewRenderer how to render the original view

I'm using tiptap and trying to extend the Paragraph node to wrap some extra stuff around its view. I used <NodeViewWrapper> and <NodeViewContent> as the guides said.
const ParagraphWrapper = () => {
return (
<NodeViewWrapper>
<NodeViewContent />
</NodeViewWrapper>
)
}
const ParagraphExt = Paragraph.extend({
addNodeView() {
return ReactNodeViewRenderer(ParagraphWrapper)
}
})
export default function App() {
const editor = useEditor({
extensions: [
Document,
Text,
ParagraphExt, // <<<< text-align was not rendered
// Paragraph, // <<<< This worked
TextAlign.configure({
types: ["paragraph"]
}),
],
content: `<p style="text-align: center">This is a paragraph</p>`,
})
return (
<>
<EditorContent editor={editor} />
<pre>{JSON.stringify(editor?.getJSON?.(), null, 2)}</pre>
</>
);
}
However, this seems to render the node from scratch. Thus, other extensions, such as textAlign no longer works.
I only need to wrap a thin layer around whatever was rendered originally. How do I do that?
Code Sandbox
You still get access to the attrs being passed to the node which is available in props. You can use that info to style your rendered content as you wish.
const ParagraphWrapper = (props) => {
const textAlign = props.node.attrs.textAlign;
return (
<NodeViewWrapper>
<NodeViewContent style={{textAlign}} />
</NodeViewWrapper>
);
};

Displaying a list of Markers with React

im trying to display a list of Markers with lat and lng stored on my mongodb database.
Im using the google-maps-react and this is my child map component
import {
Map,
InfoWindow,
Marker,
GoogleApiWrapper,
Polygon
} from 'google-maps-react';
import React, { Component } from 'react';
export class MapContainer extends Component {
render() {
const coords = this.props.initialCenter;
const position = this.props.position;
const paths = this.props.paths;
const style = this.props.style;
const center = this.props.center;
console.log(this.props);
return (
<Map
google={this.props.google}
zoom={18}
initialCenter={coords}
style={style}
center={center}
>
<Marker
onClick={this.onMarkerClick}
name={'Current location'}
position={position}
/>
<InfoWindow onClose={this.onInfoWindowClose}>
<div>
<h1>Test</h1>
</div>
</InfoWindow>
<Polygon
paths={paths}
strokeColor='#0000FF'
strokeOpacity={0.8}
strokeWeight={2}
fillColor='#0000FF'
fillOpacity={0.35}
/>
</Map>
);
}
}
export default GoogleApiWrapper({
apiKey: process.env.REACT_APP_GOOGLE_MAPS_API_TEST
})(MapContainer);
I get the coordinates from my endpoint here
const centers = this.props.places.places.map(place => {
return {
lat: place.center[0],
lng: place.center[1]
};
});
And im trying to display the list like this:
const position = { ...centers} ->does nothing
//const position = { lat: 41.53113384600326, lng: -8.619018495082855 }; -> prints one Marker
//const position = centers[0] -> prints one Marker
Im using that child component like this:
<MapContainer
initialCenter={initialCenter}
position={position}
paths={paths}
style={style}
center={center}
/>
Any help on this ?
EDIT:
Changed child component to
<Marker
onClick={this.onMarkerClick}
name={'Current location'}
position={{ position }}
/>
And on parent:
Where centers is:
<MapContainer
initialCenter={initialCenter}
paths={paths}
style={style}
center={center}
position={centers.map(p => (
<Marker
onClick={() => this.onMarkerClick(p)}
name={'Current location'} // You should probably have a "name" field for each positions
position={p}
/>
))}
></MapContainer>
const centers = this.props.places.places.map(place => {
return {
lat: place.center[0],
lng: place.center[1]
};
});
Still not showing
You need to send the array of position as props to your component, and then render them all like this:
this.props.positions.map(p => <Marker
onClick={() => this.onMarkerClick(p)}
name={'Current location'} // You should probably have a "name" field for each positions
position={p}
/>)

React native props,ref value is undefined inside keyboard hide event?

i am trying to clear my Textinput focus inside keyboard hide event,but i am not able to get reference
inside keyboard hide event method.i tried to print props value it also getting undefined
constructor (props) {
this.inputs = {};
}
_keyboardDidHide () {
console.log("value"+this.props);
this.inputs['inputValue'].blur();
}
componentWillMount () {
this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this._keyboardDidHide);
}
componentWillUnmount () {
this.keyboardDidHideListener.remove();
}
<TextInput
ref={input => {
this.inputs['inputValue'] = input;
}}
autoFocus={true}
blurOnSubmit={false}
/>
let me know how to clear the TextInput focus on _keyboardDidHide method.
I'm not 100% sure what you're trying to do here, however I assume you want to at least get the info out from your input.
No need for that ref magic there though, just use simple react state changes.
class InputWrapper extends React.Component {
constructor() {
super();
this.state = {
input: ''
};
this.handleInput = this.handleInput.bind(this);
}
handleInput(input) {
this.setState({input});
}
render() {
return (
<TextInput onChangeText={this.handleInput} />
);
}
}
This will give you a TextInput Component with control over the input.
Now you should add a componentDidUpdate method as well, that prints out the current state, so you can observe what is happening when you change the input value.
componentDidUpdate() {
console.log(this.state);
}
As for bluring and such, you should definitely check out the documentation on TextInput : https://facebook.github.io/react-native/docs/textinput.html
Additionally, might I suggest to jump into the lifecycle documentation of react itself, plus checking up on props vs state in react. It is a confusing concept in the beginning and you should definitely revisit it.
As for blurring the input, simply do this:
<TextInput
ref={input => this.input = input}
/>
And then you can call:
this.input.blur();
wherever you want.
Also, do not forget to bind your _keyboardDidHide callback within your constructor or when adding it as the listener callback, like so
this._keyboardDidHide = this._keyboardDidHide.bind(this)
Keyboard.addListener('keyboardDidHide', this._keyboardDidHide.bind(this));
Hope this helps

Is it possible to capitalize first letter of text/string in react native? How to do it?

I have to capitalize first letter of text that i want to display. I searched for it but i cant found clear thing to do that, also there is no such props for text in react native official documentation.
I am showing my text with following format:
<Text style={styles.title}>{item.item.title}</Text>
or
<Text style={styles.title}>{this.state.title}</Text>
How can I do it?
Suggestions are welcome?
Write a function like this
Capitalize(str){
return str.charAt(0).toUpperCase() + str.slice(1);
}
then call it from <Text> tag By passing text as parameter
<Text>{this.Capitalize(this.state.title)} </Text>
You can also use the text-transform css property in style:
<Text style={{textTransform: 'capitalize'}}>{this.state.title}</Text>
React native now lets you make text uppercase directly with textTransform: 'capitalize'. No function necessary.
import React from 'react'
import { StyleSheet, Text } from 'react-native'
// will render as Hello!
export const Caps = () => <Text style={styles.title}>hello!</Text>
const styles = StyleSheet.create({
title: {
textTransform: 'capitalize'
}
})
Instead of using a function, a cleaner way is to write this as a common component.
import React from 'react';
import { View, Text } from 'react-native';
const CapitalizedText = (props) => {
let text = props.children.slice(0,1).toUpperCase() + props.children.slice(1, props.children.length);
return (
<View>
<Text {...props}>{text}</Text>
</View>
);
};
export default CapitalizedText;
Wherever you're using <Text>, replace it with <CapitalizedText>
just use javascript.
text.slice(0,1).toUpperCase() + text.slice(1, text.length)
TextInput have this to handle using
autoCapitalize enum('none', 'sentences', 'words', 'characters')
for example try like this
<TextInput
placeholder=""
placeholderTextColor='rgba(28,53,63, 1)'
autoCapitalize = 'none'
value ='test'
/>
this worked for me!
labelStyle:{
textTransform: 'capitalize',
fontSize:20,
},
Since this is very general functionality I put it in a file called strings.js under my library:
// lib/strings.js
export const CapitalizeFirstLetter = (str) => {
return str.length ? str.charAt(0).toUpperCase() + str.slice(1) : str
}
And simply import it in the components that need it:
import React from 'react';
import { View, Text } from 'react-native';
import { CapitalizeFirstLetter} from 'lib/strings'
export default function ComponentWithCapitalizedText() {
return <Text>CapitalizeFirstLetter("capitalize this please")</Text>
}
I just added a prototype function, based on #mayuresh answer
String.prototype.Capitalize = function() {
return this.charAt(0).toUpperCase() + this.slice(1);
}
and use it like this:
myStr.Capitalize()
If you want to capitalize only the first letter of the input:
function CapitalizeFirstLetterOfInput () {
const onInputUppercase = (e) => {
let firstLetter = e.target.value.charAt(0);
e.target.value = firstLetter.toUpperCase() + e.target.value.slice(1);
};
return (
<div>
<input onInput={onInputUppercase}/>
</div>
)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.1/umd/react-dom.production.min.js"></script>
if anyone interested doing it by just css/style
<strong style={{textTransform: 'capitalize'}}>{props.alert.type}!
here inner {} is for object {textTransform: 'capitalize'}
This answer worked for me:
text.slice(0,1).toUpperCase() + text.slice(1, text.length)
I used it with a props in an alt tag:
`${(props.image).slice(0,1).toUpperCase() + (props.image).slice(1, (props.image).length)}`
Then I guess you can apply that to any text you want.

Create an interactive SVG component using React

Let's say I have an SVG element with paths for all US states.
<svg>
<g id="nh">
<title>New Hampshire</title>
<path d="m 880.79902,142.42476 0.869,-1.0765 1.09022,..." id="NH" class="state nh" />
</g>
...
</svg>
The SVG data is saved in a separate file with a .svg extension. Say I want to create a React component of that map, with complete control over it so that I can modify the styling of individual states based on some external input.
Using Webpack, as far as I can tell, I have two options for loading the SVG markup: Insert it as raw markup using the raw-loader and create a component using dangerouslySetInnerHTML:
var InlineSvg = React.createClass({
render() {
var svg = require('./' + this.props.name + '.svg');
return <div dangerouslySetInnerHTML={{__html: svg}}></div>;
}
});
or manually convert the markup to valid JSX:
var NewComponent = React.createClass({
render: function() {
return (
<svg>
<g id="nh">
<title>New Hampshire</title>
<path d="m 880.79902,142.42476 0.869,-1.0765 1.09022,..." id="NH" className="state nh" />
</g>
...
</svg>
);
});
Finally, let's say that in addition to the SVG map, there's a simple HTML list of all the states. Whenever a user hovers over a list item, the corresponding SVG path should shift fill color.
Now, what I can't seem to figure out is how to update the React SVG component to reflect the hovered state. Sure, I can reach out into the DOM, select the SVG state by classname and change its color, but that doesn't seem to be the "react" way to do it. A pointing finger would be much appreciated.
PS. I'm using Redux to handle all communication between components.
You need to do two things:
1) Set an event listener on each list item to inform your app of the highlighted item.
<li
onMouseOver={() => this.handleHover('NH')}
onMouseOut={() => this.handleUnhover()}
>
New Hampshire
</li>
2) Capture the data, and propagate it your SVG component.
This is the more complicated part, and it comes down to how you've structured your app.
If your entire app is a single React component, then handleHover would simply update the component state
If your app is divided into multiple components, then handleHover would trigger a callback passed in as a prop
Let's assume the latter. The component methods might look like this:
handleHover(territory) {
this.props.onHighlight(territory);
}
handleUnhover() {
this.props.onHighlight(null);
}
Assuming you have a parent component, which contains both the SVG map and the list, it might look something like this:
class MapWrapper extends React.Component {
constructor(props) {
super(props);
this.state = {
highlighted: null;
};
}
setHighlight(territory) {
this.setState({
highlighted: territory
});
}
render() {
const highlighted = { this.state };
return (
<div>
<MapDiagram highlighted={highlighted} />
<TerritoryList onHighlight={(terr) => this.setHighlight(terr)} />
</div>
);
}
}
The key here is the highlighted state variable. Every time a new hover event occurs, highlighted changes in value. This change triggers a re-render, and the new value is passed onto MapDiagram which can then determine which part of the SVG to highlight.

Resources