google is not defined in angular 4 app - google-maps

Hello I am trying to use an npm package "#types/googlemaps": "^3.30.7", and I am trying to implement a component that will allow me to create any of the things that I need to create as google isn't defined.
I have ran npm install many times.
I import it like: import {} from '#types/googlemaps';
and implement it like:
ngOnInit(): void {
var location = this.googleMapService.getCurrentLocation();
let mapProp = {
center: new google.maps.LatLng(this.googleMapService.currentLatitude, this.googleMapService.currentLogitude),
zoom: 15,
mapTypeId: google.maps.MapTypeId.HYBRID
};
this.map = new google.maps.Map(this.googleMap.nativeElement, mapProp);
this.map.addListener('click', (event) => this.addMarker(event));
this.addMarkerAtCurrentLocation();
}
if someone could tell me what to look for or why it is undefined i would appreciate it.

I have found the issue. On my index.html page I needed to add
<script src="http://maps.googleapis.com/maps/api/js"></script>
in the script section.

Related

loading google map from another component with vue router

I have an issue about google map loading. the thing is in #App component reading google map
component from <router-view> but with this way it's giving the error: "ReferenceError: google is not defined". first I thought I am missing something inside initMap() but no, because if I try to paste map method into the app.vue then google map running without a problem.
By the way my api is inside the public/index.html
<script async defer src="https://maps.googleapis.com/maps/api/js?key=MY_API&callback=initMap"></script>
the map.vue component:
<template>
<div id="map" class="map"></div>
</template>
<script>
export default {
mounted(){
this.initMap();
},
methods: {
initMap(){
let options = {
center: {lat: 34.693725, lng: 135.502254},
zoom: 15,
mapTypeId: "roadmap"
};
let map = new google.maps.Map(document.getElementById("map"), options);
}
}
}
</script>
so what do you think problem is and how can I map component work with the <router-view>
The Vue Cookbook has an example for loading google maps, which uses google-maps-api-loader to wrap the loading process into a promise.
The promise from the loader is awaited in the mount hook in the consuming component.
Here's a codesandbox demonstrating the approach.

How to call a function inside methods when click a button in a Google Maps' InfoWindow?

I'm building a Google Maps app using Vue. (I use .vue instead of single file component)
i have a number of markers on the map and an InfoWindow tie to each of them with this code.
Markers section in the MapComponent.vue
this.markers[layer.lyr_id][node.nod_id] = new google.maps.Marker({
icon: {
scaledSize: configuration.marker.icon.scaledSize,
url: layer.icon_nod_sub_url,
},
position: {
lat: node.lat,
lng: node.lon,
},
map: mapCanvas,
});
InfoWindow section in the MapComponent.vue
this.infoWindows[layer.lyr_id][node.nod_id] = new google.maps.InfoWindow({
content: `<strong>${node.dflt_name}</strong>
<p>${node.dflt_info}</p>
<button v-on:click="this.addToPath(${node.nod_id})">Add this node to the path</button>`,
});
EventListener section in the MapComponent.vue
this.markers[layer.lyr_id][node.nod_id].addListener('click', () => {
this.infoWindows[layer.lyr_id][node.nod_id].open(
mapCanvas,
this.markers[layer.lyr_id][node.nod_id]
)
});
What I'm struggling right now is how to make the <button> in the InfoWindow section calls a function defined in the methods which looks like this
methods: {
...
addToPath(nod_id) {
alert(nod_id)
console.log(nod_id)
}
...
}
Right now when I click the button it does absolutely nothing, no warning, no error at all.
What should I do to get it work?
Note:
I have searched and found this similar question. However, it doesn't work for my case because I use this way to import (which it would be too late to change the way to import). When I use the solution in that question, I got the error that says TypeError: vm is undefined. So it didn't help me.
Thank you in advance!
Assign vue to a constant such as
const vm = new Vue({
el: '#app',
components: { 'map-component': MapComponent }
});
I then usually assign a ref to it:
<map-component ref="map-component">...</map-component>
And then you can all the methods inside the component with
vm.$refs.map-component.addToPath()

Google Map not rendering correctly after first view with Backbone.js

Im creating a mobile app with Phonegap, Backbone.js, Require.js and PageSlider (https://github.com/ccoenraets/PageSlider).
I want to display a simple Google Map with a marker. The template looks like:
<div class='main-content' id='map-container'>
<a href="geo:51.903679,-8.468274">
<div id="map-canvas"></div>
</a>
</div>
Here is the view:
define(function (require) {
"use strict";
var $ = require('jquery'),
_ = require('underscore'),
Backbone = require('backbone'),
tpl = require('text!tpl/Map.html'),
side_nav = require('text!tpl/SideNav.html'),
template = _.template(tpl),
map, myLatlng, mapOptions, marker;
return Backbone.View.extend({
initialize: function () {
this.render();
},
initMap: function () {
myLatlng = new google.maps.LatLng(51.903679, -8.468274);
mapOptions = {
center: myLatlng,
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(this.$el.find('#map-canvas')[0],
mapOptions);
marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: 'Christians Brothers College Cork'
});
},
render: function () {
this.$el.html(template({side_nav:side_nav}));
this.initMap();
},
});
});
Here is a link to the app. When you click on "location", the map renders perfectly. But when you navigate anywhere else, then back to location, only a tiny portion of the map can be seen in the top left hand corner.
I tried doing, which was suggested here:
google.maps.event.trigger(map, 'resize').
but to no avail. Any ideas?
Your view works on a node not appended to the DOM, thus without size, a situation Google Map is not very fond of. It is your router, via PageSlider, that does append the node after your render function has occurred.
Here is a demo of your predicament : http://jsfiddle.net/3C7g3/
You have several options to solve it:
call google.maps.event.trigger(map, 'resize') after the node is inserted into the DOM (this bit of code corresponds to your router entry for the map)
// assuming you stored the map object in your view
require(["app/views/Map"], function (Map) {
var view = new Map();
slider.slidePage(view.$el);
google.maps.event.trigger(view.map, 'resize');
});
http://jsfiddle.net/3C7g3/1/
insert the node into DOM before calling render. In your case, that probably means removing render from the view.initialize and calling view.render after container.append(page); in your slidePageFrom method.
http://jsfiddle.net/3C7g3/2/
a more hackish way would be to temporarily add the element to the DOM, apply Google Maps, and then remove it from the DOM
initMap: function () {
// assuming a temp class that hides the element. For example,
// .temp {position: absolute; visibility:hidden; }
this.$el.addClass('temp');
$('body').append(this.$el);
// ...
this.$el.remove();
this.$el.removeClass('temp');
}
http://jsfiddle.net/3C7g3/3/

Working with Google Maps, Stamen Tiles (an existing tile library) and Require.js?

I am trying to write a module`to load a Stamen tile map under Require.js, but I'm unsure how to best use it with Require.
If you haven't seen Stamen maps before, their site is at Stamen Maps.
This is the code for the map view, view.js
define([
'jquery',
'underscore',
'backbone',
'maps',
'text!templates/map/view.html'
], function($, _, Backbone, maps, mapTemplate){
var mapView = Backbone.View.extend({
el: $(".map"),
displayMap: function() {
this.options = {
center: new maps.LatLng(-37.8, 144.9),
zoom: 11,
mapTypeId: google.maps.MapTypeId.ROADMAP,
scrollwheel: false
};
this.render();
},
render: function(){
var compiledTemplate = _.template(mapTemplate);
var $el = $(this.el);
$el.html(compiledTemplate);
this.map = new maps.Map($el.find('.map').get(0), this.options);
}
});
return new mapView;
});
I am loading the maps API following modules:
map.js
define(['google!maps/3/sensor=false'], function() {
return google.maps;
});
Which has the dependency of google.js
define(['http://www.google.com/jsapi?key=THE_API_KEY&callback=define'], {
load: function( name, req, load, config ) {
if (config.isBuild) {
onLoad(null);
} else {
var request = name.split('/');
google.load(request[0], request[1], {
callback: load,
language: 'en',
other_params: ((typeof request[2] === 'string')?request[2]:'')
});
}
}
});
The issue is that the Stamen maps layers appear to edit the Google Maps instance directly. You can see the Stamen maps implementation here:
http://maps.stamen.com/js/tile.stamen.js?v1.1.1
google.maps.StamenMapType = function(name) {
//Implementation
}
It seems to rely on the global google.maps object, which is where I believe the issue is coming from.
I'm unsure how to best rewrite the Stamen plugin to be require.js friendly, or if I need to, and I am really keen on using it. Unless I take Google Maps and Stamen out of Require.js and load them normally (like I do with Modernizr) but I'd much prefer to try and do it the Require.js way. If there is such a thing.
Any advice or tips would be much appreciated.
I'm responsible for tile.stamen.js. Sorry for the headache.
The problem here is that our script needs access to the Google Maps namespace (google.maps) so that it can create the StamenMapType class and have it inherit methods from Google's ImageMapType. If you absolutely need to use RequireJS (which I wouldn't suggest, exactly because it makes simple stuff like this awkward), you'll need to rewrite the whole Google-specific portion of tile.stamen.js (lines 155-177) to look something like this:
exports.makeStamenMapType = function(name, gmaps) {
if (!gmaps) gmaps = google.maps;
var provider = getProvider(name);
return new gmaps.ImageMapType({
"getTileUrl": function(coord, zoom) {
var index = (zoom + coord.x + coord.y) % SUBDOMAINS.length;
return [
provider.url
.replace("{S}", SUBDOMAINS[index])
.replace("{Z}", zoom)
.replace("{X}", coord.x)
.replace("{Y}", coord.y)
];
},
"tileSize": new gmaps.Size(256, 256),
"name": name,
"minZoom": provider.minZoom,
"maxZoom": provider.maxZoom
});
};
Then you'd use:
var toner = makeStamenMapType("toner", gmaps);
where gmaps is your required Google Maps API object.

How do I upload a .gpx file from localhost to google maps (v3) ?

I'm new to the Google Maps API and I'm working on localhost.
I want to add the ability for a user to upload their .gpx file and visualize it on the Google Map.
I've found this AJAX function wich works fine when I hardcode the .gpx file, but when I try to import the file from my computer, I got a grey screen for short second which then disappears.
Any idea or solution for this problem is more than welcome.
Thanks in advance.
function get_file() {
var fileInput = document.getElementById("file_upload");
var filename = fileInput.value;
var myOptions = {
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
loadGPXFileIntoGoogleMap(map, filename);
}
function loadGPXFileIntoGoogleMap(map, filename) {
$.ajax({url: filename,
dataType: "xml",
success: function(data) {
var parser = new GPXParser(data, map);
parser.setTrackColour("#ff0000"); // Set the track line colour
parser.setTrackWidth(5); // Set the track line width
parser.setMinTrackPointDelta(0.001); // Set the minimum distance between track points
parser.centerAndZoom(data);
parser.addTrackpointsToMap(); // Add the trackpoints
parser.addWaypointsToMap(); // Add the waypoints
}
});
}
There is no way to access filesystem from JavaScript.
This is a security issue. To resolve your issue I can see only one option: You should have server-side functionality that will temporary store user uploaded data. And then you can load user defined .gpx files from server.