<ReactMapGL/> component shows blank screen - reactjs

I was following lama dev youtube channel's video for using mapbox in reactjs.
But when I run the reactjs script, my map component is empty.
video:
https://youtu.be/9oEQvI7K-rA
source code:
https://github.com/safak/youtube/tree/mern-travel-app
my code
import * as React from 'react';
import { useState } from 'react';
import ReactMapGL from 'react-map-gl';
function App() {
const [viewport, setViewport] = useState({
width: "100vw",
height: "100vh",
latitude: 46,
longitude: 17,
zoom: 8,
});
return (
<div className="App">
<ReactMapGL
{...viewport}
mapboxApiAccessToken = {process.env.REACT_APP_MAPBOX}
onViewportChange={nextViewport => setViewport(nextViewport)}
/>
</div>
);
}
export default App;
I followed the coding and in the react part, I created the .env file, installed and imported react-map-gl and used the . For some reason I see only blank screen instead of a map.
I tried the example code from the uber library visgl.github.io, also the source code that you have provided, still the screen was blank.
followed these solutions:
Mapbox blank map React-map-gl | ReactJS
react-map-gl: Map Does Not Appear
Map not showing up when using react-map-gl and create-react-app
but still the Component is empty.
Any help would be useful, thanks!
EDIT 1:
I found this error in the firefox console:
An error occurred while parsing the WebWorker bundle. This is most likely due to improper transpilation by Babel; please see https://docs.mapbox.com/mapbox-gl-js/guides/install/#transpiling

After the comment from J-007, I added these lines below the previous import lines:
import mapboxgl from 'mapbox-gl';
mapboxgl.workerClass = require('worker-loader!mapbox-gl/dist/mapbox-gl-csp-worker').default;
and the map is working fine now.
EDIT:
This worked only in one project-
https://codesandbox.io/s/react-test-ivbkv?file=/src/App.js
then it didn't work in the example provided in
http://visgl.github.io/react-map-gl/docs/get-started/get-started
Then I found -
https://medium.com/geekculture/building-an-interactive-map-with-mapbox-react-f335384f4863:
and using npx create-react-app projectname exactly as mentioned in this article, i find the map working even in http://visgl.github.io/react-map-gl/docs/get-started/get-started script.
EDIT 2:
Copy pasting code from the Medium article (just in case) -
npx create-react-app mapbox-project
cd mapbox-project
npm i react-map-gl react-map-gl-geocoder
npm start
import React, { Component } from 'react';
import ReactMapGl from 'react-map-gl'
import 'mapbox-gl/dist/mapbox-gl.css';
const mapboxToken = 'YOUR API KEY'
class Map extends Component {
constructor() {
super()
this.state = {
viewport: {
width: '100vw',
height: '100vh',
latitude: 40.78343,
longitude: -73.96625,
zoom: 11
}
}
this.handleViewportChange = this.handleViewportChange.bind(this)
}
handleViewportChange(viewport) {
this.setState(prevState => ({
viewport: {...prevState.viewport, ...viewport}
}))
}
render() {
return (
<ReactMapGl
{...this.state.viewport}
onViewportChange={viewport => this.setState({viewport})}
mapboxApiAccessToken={mapboxToken}
mapStyle="mapbox://styles/mapbox/streets-v10"
/>
)
}
}
export default Map;

What worked for me, was from this page:
http://visgl.github.io/react-map-gl/docs/get-started/get-started
npm install --save react-map-gl mapbox-gl
whereas, I believe the tutorial was just react-map-gl

Related

How to do Video Trimmer in Reactjs

I want to do a video trimmer in reactjs. I have searched and I got the package
Package name: npm i react-video-trimmer
Here is the example of this package,
Example code:
import React from "react";
import ReactVideoTrimmer from "react-video-trimmer";
import "react-video-trimmer/dist/style.css";
const Trimmer = () => {
const handleVideoEncode = React.useCallback(result => {
console.log("Encoding Result:", result);
});
return (
<div>
<ReactVideoTrimmer
onVideoEncode={handleVideoEncode}
timeRange={{ start: 10, end: 100 }}
/>
</div>
);
};
But, I don't know how to feed the video URL which I have to trim and I'm not clear about how this package is working.
So, please tell me how this package is working. And, Is there any alternative way to create a video trimer in Reactjs?

how to use #googlemaps/js-api-loader in React?

I wanna use Google Maps API in React.
I read this article and found out that some packages were released recently.
But I don't know even if I look at the example.
How can I use Google Maps in React?
I want to take a marker, change the marker icon.
Please help me...
Definitely understand that there are packages that help you load Google Map and the Javascript API, e.g.
https://www.npmjs.com/package/google-map-react
https://www.npmjs.com/package/#react-google-maps/api
I used google-map-react before, but now I need a more flexible way to load the Google Maps JavaScript API script.
For those like me who got here by searching for how to use #googlemaps/js-api-loader in React, here is some code sample.
install the npm package:
npm i #googlemaps/js-api-loader
code sample:
import React, { Component } from 'react';
import { Loader } from '#googlemaps/js-api-loader';
const loader = new Loader({
apiKey: "YOUR_API_KEY"
version: "weekly",
libraries: ["places"]
});
export default class DemoComponent extends Component {
constructor(props) {
super(props);
this.state = {};
}
componentDidMount() {
let self = this;
const defaultMapOptions = {
center: {
lat: 40.762312,
lng: -73.979345
},
zoom: 11
};
loader.load().then((google) => {
const map = new google.maps.Map(
self.googleMapDiv,
defaultMapOptions);
/*
store them in the state so you can use it later
E.g. call a function on the map object:
this.state.map.panTo(...)
E.g. create a new marker:
new this.state.google.maps.Marker(...)
*/
this.setState({
google: google,
map: map
});
});
}
render() {
return (
<div
ref={(ref) => { this.googleMapDiv = ref }}
style={{ height: '100vh', width: '100%' }}>
</div>
)
}
}
Have you checked out this package and its documentation:
https://www.npmjs.com/package/#react-google-maps/api
I've used it to create a google map inside a React functional component.
There are other react google map packages out there as well.

Include custom geocoding results in mapbox gl as part of a react app

I'm trying to pass a function as the localGeocoder parameter of a mapbox gl geocoder instance (docs here). I want to do this as part of a react app. The geocoder and map mostly work fine, but I'm not even entering into the function I'm passing when I do geocoding searches. What have I got wrong with this setup?
I know that the localGeocoder function is supposed to return an array of geojson features in the carmen geojson format, but since I couldn't get this to work I just put a console.log() statement in the function and looking at the dev tools in the browser and it's not executing. The main parts of the component are below, but you'll need to fill in your own mapbox accessToken to get it to work. I know that mapbox has a working example of how to pass a localGeocoder function, but that doesn't use react and I think that's where I'm going wrong here so that example isn't really much help to me.
import React from 'react';
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css'
import Geocoder from 'mapbox-gl-geocoder';
import 'mapbox-gl-geocoder/dist/mapbox-gl-geocoder.css'
import './map.scss';
mapboxgl.accessToken = ENTER_YOUR_MAPBOX_ACCESS_TOKEN_HERE;
export class Map extends React.Component {
constructor(props) {
super(props);
this.state = {
lng: -73.9392,
lat: 40.8053,
zoom: 15
};
this.forwardGeocoder = this.forwardGeocoder.bind(this);
}
forwardGeocoder(query) {
console.log('QUERY:', query);
}
componentDidMount() {
const map = new mapboxgl.Map({
container: this.mapContainer,
style: 'mapbox://styles/mapbox/streets-v11',
center: [this.state.lng, this.state.lat],
zoom: this.state.zoom,
zoomAnimation: false
});
const geocoder = new Geocoder({
accessToken: mapboxgl.accessToken,
mapboxgl: mapboxgl,
autocomplete: false,
localGeocoder: this.forwardGeocoder,
proximity: {longitude: this.state.lng, latitude: this.state.lat}
})
map.addControl(geocoder);
}
render() {
return <div ref={el => this.mapContainer = el} className='mapContainer' />
}
}
Alex,
I did a codesandbox to you check (just need to add you API Key).
If you search for coffee, you will see QUERY: coffee in console.
So, the only difference from your code to mine is:
mapbox-gl-geocoder import.
You are doing like this:
import Geocoder from 'mapbox-gl-geocoder';
import 'mapbox-gl-geocoder/dist/mapbox-gl-geocoder.css'
And I'm doing like this:
import Geocoder from "#mapbox/mapbox-gl-geocoder";
import "#mapbox/mapbox-gl-geocoder/dist/mapbox-gl-geocoder.css";
As i donĀ“t know how you added the mapbox-gl-geocoder package, i will describe how i did:
I'm using yarn:
yarn add react-map-gl-geocoder
If you are using npm:
npm install react-map-gl-geocoder
After that, my package.json has this versions:
"react": "^16.13.1",
"mapbox-gl": "^1.3.1",
"#mapbox/mapbox-gl-geocoder": "^4.7.0",
Maybe that could be the issue. Hope it works for you.

How to run React JS build in React-Native Webview?

I created complete offline ReactJS web application and I want to run it from android application from Web View using React-Native.
I followed the following procedure to do so:
1. I created a compiled ReactJS web application got the build using the following command:
npm run build
Then I created react-native project and placed the build folder with following architecture
I updated App.js with the following content:
import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View, WebView} from 'react-native';
import {roscon} from "./build/index.html";
type Props = {};
export default class App extends Component<Props> {
render() {
return (
<View style={{height: 300, width: 300,overflow:'hidden' }}>
<WebView
source={{uri: roscon}}
scalesPageToFit={true}
domStorageEnabled={true}
javaScriptEnabled={true}
startInLoadingState={true}
/>
</View>
);
}
}
After running this code I expected it to run my ReactJS Web application, instead I got white screen.
Can you please tell what can be the causing issues and how i can make my ReactJS Web App run on react-native?
Note: I was able to run generated build folder using npm command
serve -s build
But I still can't figure out how to port it to react-native project as WebView
After research and testing, I found a solution.
The main issue i found was the compiled build folder is rendered as static html. And it needed a server to serve pages.
So, I followed this link for getting build project to get it up and running
Then, integrating it with nodejs Android Project Samples to get my build folder running in android as a Webview.
Note: I also tried react-snapshot and react-snap but they didn't gave satisfactory results.
Try to require the html file correctly and pass it in to source prop in this way:
<WebView
source={require('./build/index.html')}
/>
Install
npm install react-native-react-bridge
These are used to render React app in WebView
npm install react-dom react-native-webview
Requirements
react 16.8+
react-native 0.60+
Usage
Fix metro.config.js to use babelTransformer from this library.
module.exports = {
transformer: {
babelTransformerPath:
require.resolve('react-native-react- >.
.bridge/lib/plugin'),
...
},
};
Make entry file for React app. web.js
import React, { useState } from "react";
import {
webViewRender,
emit,
useSubscribe,
} from "react-native-react-bridge/lib/web";
const Root = () => {
const [data, setData] = useState("");
// useSubscribe hook receives message from React Native
useSubscribe((message) => {
if (message.type === "success") {
setData(message.data);
}
});
return (
<div>
<div>{data}</div>
<button
onClick={() => {
// emit sends message to React Native
// type: event name
// data: some data which will be serialized by JSON.stringify
emit({ type: "hello", data: 123 });
}}
/>
</div>
);
};
// This statement is detected by babelTransformer as an entry point
// All dependencies are resolved, compressed and stringified into one file
export default webViewRender(<Root />);
Use the entry file in your React Native app with WebView.
import React from "react";
import WebView from "react-native-webview";
import { useBridge } from "react-native-react-bridge";
import webApp from "./WebApp";
const App = () => {
// useBridge hook create props for WebView and handle communication
// 1st argument is the source code of React app
// 2nd argument is callback to receive message from React
const { ref, source, onMessage, emit } = useBridge(webApp, (message) => {
// emit sends message to React
// type: event name
// data: some data which will be serialized by JSON.stringify
if (message.type === "hello" && message.data === 123) {
emit({ type: "success", data: "succeeded!" });
}
});
return (
<WebView
// ref, source and onMessage must be passed to react-native-webview
ref={ref}
source={source}
onMessage={onMessage}
/>
);
};

react-leaflet mapboxgl integration not working

following the answer in this page :
Render mapbox vector tiles inside react-leaflet?
When i export MapBoxGLLayer and import it to my main class,
like
import MapBoxGLLayer from './MapBoxGLLayer';
and try to access it in my render function, like:
<Map>
<MapBoxGLLayer
accessToken={MAPBOX_ACCESS_TOKEN}
style='https://style.example.com/style.json'
/>
</Map>
i'm getting this error which is pretty consistent.
MapLayer.js:77 Uncaught TypeError: Cannot read property 'layerContainer' of undefined
at VectorgridLayer.get (MapLayer.js:77)
at VectorgridLayer.componentDidMount (MapLayer.js:38)
There is no leaflet to the props.
I don't know what am I doing wrong here.
Taking hints from the answer you mentioned, I was able to get it working.
Your MapBoxGLLayer.js
import L from "leaflet";
import {} from "mapbox-gl-leaflet";
import PropTypes from "prop-types";
import { GridLayer, withLeaflet } from "react-leaflet";
class MapBoxGLLayer extends GridLayer {
createLeafletElement(props){
return L.mapboxGL(props);
}
}
export default withLeaflet(MapBoxGLLayer);
The missing thing was the withLeaflet HOC.
Usage:
npm i mapbox-gl-leaflet
Add mapbox-gl-js and css to index.html
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.51.0/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.51.0/mapbox-gl.css' rel='stylesheet' />
// Import the MapBoxGLLayer component mentioned above.
class App extends Component {
state = {
center: [51.505, -0.091],
zoom: 13
};
render() {
return (
<div>
<Map center={this.state.center} zoom={this.state.zoom}>
<MapBoxGLLayer
accessToken={MAPBOX_ACCESS_TOKEN}
style="mapbox://styles/mapbox/streets-v9"
/>
</Map>
</div>
);
}
}
You can find the working example here:https://codesandbox.io/s/ooypokn26y
Add your own mapbox token to see it working.
It seems to be a bug in mapbox-gl-leaflet version 0.0.3 that is the "latest" in npm and was released two years ago.
onRemove: function (map) {
if (this._map.options.zoomAnimation) {
L.DomEvent.off(this._map._proxy, L.DomUtil.TRANSITION_END, this._transitionEnd, this);
}
map.getPanes().tilePane.removeChild(this._glContainer);
this._glMap.remove();
this._glMap = null;
}
The object this.map._proxy is not defined. Solution is to disable zoom animations with zoomAnimation={false} in the React Map Component. Then the branch is not taken in mapbox-gl-leaflet and you won't get this error.
This problem is solved in the master branch of mapbox-gl-leaflet in GitHub:
https://github.com/mapbox/mapbox-gl-leaflet/blob/954875e2e4269db313c99d522689bc08f4aadad2/leaflet-mapbox-gl.js
So try to update you libs.

Resources