I started using vue. How can I include Google API to my page? This is my code:
<template>
<div id="map"></div>
</template>
<script>
export default {
methods: {
init () {
var map
map = new google.maps.Map(document.getElementById('map'), {
zoom: 16,
center: new google.maps.LatLng(-33.91722, 151.23064),
mapTypeId: 'roadmap'
})
}
}
}
</script>
Where can I set
<script src="https://maps.googleapis.com/maps/api/js?key=YourKey&callback=App.map" async defer></script>
The script element goes in your index.html file, for example:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="app"></div>
</body>
<script src="https://maps.googleapis.com/maps/api/js?key=YourKey&callback=App.map" async defer></script>
</html>
If this doesnt work for you, try removing the callback from the end of the <script> element's src attribute as well as the async and defer keywords, so it looks like:
<script src="https://maps.googleapis.com/maps/api/js?key=YourKey"></script>
Then in your vue instance, call your init() function once the App component has mounted. See below:
export default {
mounted () {
this.init()
},
methods: {
init () {
var map
map = new google.maps.Map(document.getElementById('map'), {
zoom: 16,
center: new google.maps.LatLng(-33.91722, 151.23064),
mapTypeId: 'roadmap'
})
}
}
}
I'd like to put the google map api just before </body>. Make sure your vue element is called before google map api (i.e. within app.js). Put initMap as the google api's callback.
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="app">
<map lat="1.23456" lng="100.21345"></map>
</div>
<script src="app.js"></script><!-- your vue element should be here -->
<script src="https://maps.googleapis.com/maps/api/js?key=YourKey&callback=initMap" async defer></script>
</body>
</html>
And this is my code in Map.vue, which has a definition of window.initMap(..). I also have a marker (pin) inside the map.
<template>
<div>
<div ref="map" style="width: 100%; height: 200px;"></div>
</div>
</template>
export default {
props: [
'lat',
'lng'
],
mounted() {
window.initMap = () => {
this.mapElement = new google.maps.Map(this.$refs.map, {
zoom: 14,
center: {lat: this.lat, lng: this.lng}
});
this.marker = new google.maps.Marker({
position: {lat: this.lat, lng: this.lng},
map: this.mapElement
});
}
},
data() {
return {
mapElement: null,
marker: null
}
}
}
Related
I am trying to get openlayer working in alpine
but i have this error which i can't solve
Uncaught SyntaxError: ambiguous indirect export: default
(import olJf from "./dist/js/oljf.js";)
My source file
//oljf.js
import Map from 'ol/Map.js';
import OSM from 'ol/source/OSM.js';
import TileLayer from 'ol/layer/Tile.js';
import View from 'ol/View.js';
export default function olJf () {
new Map({
target: 'map',
layers: [
new TileLayer({
source: new OSM(),
}),
],
view: new View({
center: [0, 0],
zoom: 2,
}),
})
};
I compile it with vitejs and I import it in my alpine component
//compiled file
import olJf from "./dist/js/oljf.js";
document.addEventListener('alpine:init', () => {
Alpine.data('map', () => ({
latitude: false,
longitude: false,
isLoading: false,
init() {
console.log(`map for ${this.latitude}`);
console.log(window.oljf)
const mapdiv = document.getElementById('openmap_offre')
olJf()
}
})
)
})
And I call alpine
<head>
<script type="module" src="https://xxx.be/wp-content/themes/visittail/assets/js/map.js" defer></script>
</head>
<body>
<div id="openmap_offre" class="mt-3" style="width: 100%; height: 400px;" x-data="map" x-init="initMap">
</div>
</body>
I am trying to create a map using Leaflet and a Vue component. For some reason the "center: " attribute is not accepting my array coordinates for Latitude and Longitude? When I use it in the template html {{ latlng }} I get an array with the correct coordinates. Any help would be greatly appreciated.
<template>
<div id="mapContainer">{{ latlng }}</div>
</template>
<script>
import "leaflet/dist/leaflet.css";
import L from "leaflet";
import axios from 'axios';
export default {
name: "Map",
data() {
return {
map: null,
latlng: []
};
},
methods: {
get_lat_lng: function(){
axios.get('http://127.0.0.1:5000/api/get_latitude')
.then(res => this.latlng.push(res.data))
axios.get('http://127.0.0.1:5000/api/get_longitude')
.then(res => this.latlng.push(res.data))
}
},
created: function(){
this.get_lat_lng()
},
mounted() {
this.map = L.map("mapContainer", {
center: this.latlng,
zoom: 12,
});
L.tileLayer("http://{s}.tile.osm.org/{z}/{x}/{y}.png", {
attribution:
'© OpenStreetMap contributors'
}).addTo(this.map);
},
beforeDestroy() {
if (this.map) {
this.map.remove();
}
}
};
</script>
<style scoped>
#mapContainer {
width: 50vw;
height: 50vh;
}
</style>
You have hit a race condition here. The mounted() hook is called before the axios.get asynchronous call have been completed.
The sequence of calls is probably this 1.created(), 2.mounted(), 3.axios.then()
So, you will need to slightly change your logic so the map is initialized when both the creation has completed and the mount hook has been invoked.
Something like this,
add a flag for the mounted call been executed
data() {
return {
map: null,
mounted: false,
latlng: null
}
move the map creation code into a method
createMap: function() {
this.map = L.map("mapContainer", { center: this.latlng ...
at creation go fetch the data, and if already mounted, create the map
created(){
axios.all([axios.get('http://127.0.0.1:5000/api/get_longitude');
axios.get('http://127.0.0.1:5000/api/get_latitude')])
.then((longresp,latresp)=> {
this.latlng=[latresp.data,longresp.data];
if (this.mounted) this.createMap()
})
and then at mounted, check if by chance the data is already available, and if not, set the flag for the creation of the map
mounted() {
if (this.latlng) this.createMap()
this.mounted = true;
...
Create the Map when the data is available ( when axios promise is successful ).
More on promises: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
Use a indicator until content not ready.
I think there is no need for separate requests, so i merged the 2 axios requests. Your backend should return the [lat, long] array.
<template>
<div>
<!--
I also added a simple loading indicator,
obviously you can go for something more fancy like a spinner
--!>
<p v-if="loading">Loading...</p>
<div id="mapContainer">{{ latlng }}</div>
</div>
</template>
<script>
import "leaflet/dist/leaflet.css";
import L from "leaflet";
import axios from 'axios';
export default {
name: "Map",
data() {
return {
map: null,
loading: false,
latlng: []
};
},
methods: {
setupLeafletMap: function () {
this.map = L.map("mapContainer", {
center: this.latlng,
zoom: 12,
});
L.tileLayer("http://{s}.tile.osm.org/{z}/{x}/{y}.png", {
attribution:
'© OpenStreetMap contributors'
}).addTo(this.map);
}
},
mounted() {
this.loading = true;
axios.get('http://127.0.0.1:5000/api/get_latlng').then(res => {
this.latlng = res.data;
this.setupLeafletMap(); // Creating the Map here ensures that data is already loaded from server side
this.loading = false;
}).catch(error => console.error(error));
},
beforeDestroy() {
if (this.map) {
this.map.remove();
}
}
};
</script>
<style scoped>
#mapContainer {
width: 50vw;
height: 50vh;
}
</style>
Good afternoon, please tell me who knows, I am now learning to add a Google map to the site and do it with this article. I did everything as it was indicated, but the card does not work, please tell me why? Where did I make a mistake? Api-key is correct 100%. And I turn on the map in Google Cloud Platform. I use Vue cli Webpack-simple. My project on GitHub
Screenshot of a broken map
Console Error
Code of index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>google_map</title>
</head>
<body>
<div id="app"></div>
<script src="/dist/build.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=[MY_API_KEY]"></script>
</body>
</html>
Component Google.map:
<template>
<div class="google-map" :id="name"></div>
</template>
<script>
export default {
name: 'google-map',
props: ['name'],
data: function () {
return {
map: ''
}
},
computed: {
mapMarkers: function () {
return this.markers
}
},
mounted: function () {
const element = document.getElementById(this.name)
const options = {
zoom: 14,
center: new google.maps.LatLng(59.93, 30.32)
}
this.map = new google.maps.Map(element, options)
},
methods: {}
}
</script>
<style scoped>
.google-map {
width: 640px;
height: 480px;
margin: 0 auto;
background: gray;
}
</style>
Code of App.vue:
<template>
<div class="container">
<google-map :name="name"></google-map>
</div>
</template>
<script>
import googleMap from './components/googleMap.vue'
export default {
data: function () {
return {
name: 'map',
}
},
mounted: function () {
},
components: {googleMap}
}
</script>
Looking at your original code, before you started trying to use GoogleMapsLoader, your error was very simple; you were trying to use window.google in the compiled JS, before it was loaded through googleapis.com. To fix, in your index.html, simply change this:
<script src="/dist/build.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=[MY_API_KEY]"></script>
To this:
<script src="https://maps.googleapis.com/maps/api/js?key=[MY_API_KEY]"></script>
<script src="/dist/build.js"></script>
If you want to use GoogleMapsLoader, please follow the documentation they provide; you should be wrapping any calls to the Google Maps API inside a callback function that the loader calls. There are a bunch of different approaches to how to do this, and almost definitely a better way to set up a global instance, but to at least make your code work, this is how you would need to code your mounted function:
mounted: function () {
GoogleMapsLoader.KEY = '[MY_API_KEY]';
GoogleMapsLoader.load(function(google){
const element = document.getElementById(this.name)
const options = {
zoom: 14,
center: new google.maps.LatLng(59.93, 30.32)
}
this.map = new google.maps.Map(element, options)
}.bind(this));
}
I've been working with a course online using Webpack & Googlemaps, and I need to bring it to my Create-React-App application but I know create-react-app doesn't read script tags with api keys in the public/index.html file. Is there a work around instead of using google maps npm packages? I truly would appreciate any tips in the right direction.
Here is my script tag with the API_KEY :
<script async defer
src="https://maps.googleapis.com/maps/api/js?key='API_KEY'">
</script>
Here's my google maps object inside my componentDidMount():
componentDidMount(){
const {properties, activeProperty} = this.props;
const {latitude, longitude} = activeProperty;
this.map = new google.maps.Map(this.refs.map, {
center: {lat: latitude, lng: longitude},
mapTypeControl: false,
zoom: 14
});
this.createMarkers(properties);
}
To manage Google Maps library parameters, instead of referencing Google Maps library via index.html you could consider to load script resources on-demand like some popular libraries do.
For example, with ReactDependentScript component Google Maps API could be loaded like this:
class App extends Component {
render() {
const MAP_KEY = "--YOUR-KEY-GOES-HERE--";
return (
<div>
<ReactDependentScript scripts={[`https://maps.googleapis.com/maps/api/js?key=${MAP_KEY}`]}>
<Map center={{ lat: -34.397, lng: 150.644 }} zoom={3} />
</ReactDependentScript>
</div>
);
}
}
Here is a demo for your reference
Could you please write your entire component/Class? Where did you inject your script? if you did in the static html you are going to need window.google.
I wrote an example for you, remember to inject your script with API key in public/index.html
class App extends React.Component {
componentDidMount() {
this.map = new window.google.maps.Map(this.map, {
center: { lat: 41.3851, lng: 2.1734 },
mapTypeControl: false,
zoom: 14
});
}
render() {
return (
<div>
<div
style={{ width: "600px", height: "600px" }}
ref={e => (this.map = e)}
/>
</div>
);
}
}
I seemingly succesfully implemented google maps into my react app (get's user location and allows to move marker), but I'm getting random error 'TypeError: Cannot read property 'maps' of undefined'. Sometimes everything works perfectly, other time when I refresh i get this error. I'm not sure which chunk of code I should provide so maybe I'll post my full map component and index.js file
map:
import React from 'react';
class GoogleMap extends React.Component {
constructor(props) {
super(props);
//const getCoords = this.props.getCoords;
this.handleLocationError = this.handleLocationError.bind(this);
this.state = {
lat: '',
lon: ''
}
}
getCoords() {
const lat = this.state.lat;
const lon = this.state.lon;
this.props.getCoords(lat, lon)
}
componentDidMount() {
var map, infoWindow;
map = new window.google.maps.Map(document.getElementById('map'), {
center: { lat: -34.397, lng: 150.644 },
zoom: 15
});
// Try HTML5 geolocation.
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition((position) => {
var pos = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
var marker = new window.google.maps.Marker({
position: {
lat: position.coords.latitude,
lng: position.coords.longitude
},
map: map,
draggable: true,
title: 'Hello World!'
})
this.setState({
lat: position.coords.latitude,
lon: position.coords.longitude
})
this.getCoords();
document.getElementById('test').innerHTML = '<p>Want to export: Current Lat: ' + position.coords.latitude + ' Current Lng: ' + position.coords.longitude + '</p>';
map.setCenter(pos);
//marker listeners
window.google.maps.event.addListener(marker, 'dragstart', function () {
console.log('marker dotkniety');
document.getElementById('test').innerHTML = '<p>Currently dragging marker...</p>';
});
window.google.maps.event.addListener(marker, 'dragend', (e) => {
console.log('marker upuszczony');
document.getElementById('test').innerHTML = '<p>Want to export: Current Lat: ' + e.latLng.lat().toFixed(3) + ' Current Lng: ' + e.latLng.lng().toFixed(3) + '</p>';
console.log(this, 'this inside the event listener');
this.setState(({
lat: e.latLng.lat(),
lon: e.latLng.lng()
}))
this.getCoords();
});
}, () => {
this.handleLocationError(true, map.getCenter());
});
} else {
// Browser doesn't support Geolocation
this.handleLocationError(false, map.getCenter());
}
console.log('DID MOUNT');
console.log(this);
console.log(this.state);
}
handleLocationError(browserHasGeolocation, pos, map) {}
render() {
return (
<div>
<div id='map' />
<div id='test' />
</div>
)
}
}
export default GoogleMap
and index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<!--
manifest.json provides metadata used when your web app is added to the
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/latest/css/bootstrap.min.css">
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBHek4tQK4jSQhVSoxw4s4c8tz_1z3xuNI&callback=initMap">
</script>
<title>App</title>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
</body>
</html>
Ill be grateful for solutions / tips or reasons why it acts this way.
install google maps as npm package
$ npm install google-maps
and then import it on your component GoogleMapComponent.jsx:
import React from 'react';
import GoogleMapsLoader from 'google-maps';
GoogleMapsLoader.KEY = 'qwertyuiopasdfghjklzxcvbnm';
class GoogleMap extends React.Component {
constructor(props) {
super(props);
//const getCoords = this.props.getCoords;
this.handleLocationError = this.handleLocationError.bind(this);
this.state = {
lat: '',
lon: ''
}
}
componentDidMount() {
GoogleMapsLoader.load((google) => {
var map = new google.maps.Map(document.getElementById('map'), {
center: { lat: -34.397, lng: 150.644 },
zoom: 15
});
// rest of the code with maps
});
// rest of the code with react
}