Meteor reactive maps don't work as should - google-maps

I am using two brilliant packages named dburles:google-maps and mdg:geolocation. What I nee is to add a marker and change map's zoom automatically when I get user's geolocation data (after he allows it to share).
Inside Template.onCreated I have the following code:
Template.dealersMap.onCreated(function() {
Tracker.autorun(() => {
this.latLng = new ReactiveVar(Geolocation.latLng());
})
});
Then in onRendered I do the following:
Template.dealersMap.onRendered(function() {
navigator.geolocation.getCurrentPosition((position) => {
GoogleMaps.ready('exampleMap', (map) => {
let marker;
if(!this.latLng.get())
console.log('Didn\'t get the location..');
if(!marker) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(
this.latLng.get().lat,
this.latLng.get().lng
),
map: map.instance
});
} else {
marker.setPosition(this.latLng.get());
}
map.instance.setCenter(marker.getPosition());
map.instance.setZoom(11);
}, () => {
console.log('deny');
});
})
});
As result after user allows me to get his geodata nothing happens. But if user changes at least one step map zoom — everything works.
The question is — how to make this code work without letting user change map zoom?

I just removed navigator.geolocation.getCurrentPosition and now everything works fine. Here is the successful code:
Template.dealersMap.onCreated(function() {
this.latLng = new ReactiveVar();
Tracker.autorun(() => {
this.latLng.set(Geolocation.latLng());
})
});
Template.dealersMap.onRendered(function() {
this.autorun(() => {
GoogleMaps.ready('exampleMap', (map) => {
console.log('map is ready');
let marker;
if(!this.latLng.get()) {
console.log('Didn\'t get the location..');
} else {
if(!marker) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(
this.latLng.get()
.lat,
this.latLng.get()
.lng
),
map: map.instance
});
} else {
marker.setPosition(this.latLng.get());
}
}
map.instance.setCenter(marker.getPosition());
map.instance.setZoom(11);
})
})
});

You can use Tracker to rerun the once the dta is changed like, once uses share his/her location, the marker is triggered. Here is the example code:
Template.dealersMap.onRendered(function() {
var self=this;
navigator.geolocation.getCurrentPosition((position) => {
GoogleMaps.ready('exampleMap', (map) => {
self.autorun(function() { //tracker function
let marker;
if(!this.latLng.get())
console.log('Didn\'t get the location..');
if(!marker) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(
this.latLng.get().lat,
this.latLng.get().lng
),
map: map.instance
});
} else {
marker.setPosition(this.latLng.get());
}
map.instance.setCenter(marker.getPosition());
map.instance.setZoom(11);
}, () => {
console.log('deny');
}
});
})
});

Related

onMount inside a function won't re-trigger when a reactive variable changes

I need to get google maps autocomplete suggestion when I type a word on input.
maps.svelte
function inputChange() {
onMount(() => {
loader
.load()
.then((google) => {
const map = new google.maps.Map(document.getElementById('map'), mapOptions);
const markerPickUp = new google.maps.Marker({
position: {
lat: 14.6012,
lng: 120.975
},
map: map
});
const displaySuggestions = function (predictions, status) {
if (status != google.maps.places.PlacesServiceStatus.OK || !predictions) {
predictionsArray = [];
return;
}
predictionsArray = predictions;
console.log(predictionsArray);
};
const service = new google.maps.places.AutocompleteService();
const sessionToken = new google.maps.places.AutocompleteSessionToken();
service.getPlacePredictions(
{ input: $bookDetails.dropOffLocation, sessionToken: sessionToken },
displaySuggestions
);
})
.catch((e) => {
console.log(e);
});
});
}
$: $bookDetails.dropOffLocation, inputChange();
I tried to log $bookDetails.dropOffLocation after inputChange() just to see if it's bind on the input and it is. Also, the code works well without the onMount() but it's giving me errors on my terminal. It says windows not defined and it has to do with google maps. I think it needs to load the dom first that's why it gives error. I'm using #googlemaps/js-api-loader.
onMount registers a callback that executes when the component is mounted. It is not intended to be called multiple times and only ever will invoke the callback once during the lifecycle of a component.
If you just want to make sure that the component is already mounted when executing some logic, you can set a flag and use that as a guard. E.g.
let mounted = false;
onMount(() => mounted = true);
$: {
$bookDetails.dropOffLocation;
if (mounted) inputChange();
}

PixelCompare method issue

I have an issue with PixelCompare extension.
Here, i am loading it:
viewer1 = new Autodesk.Viewing.GuiViewer3D(document.getElementById('forgeViewer1'), { extensions: [ 'GoogleMapsLocator', 'Autodesk.AEC.Minimap3DExtension','Autodesk.AEC.LevelsExtension','Autodesk.DocumentBrowser','Autodesk.ToolbarExtension' ,'Autodesk.Viewing.PixelCompare'] });
Then im trying to use it :
viewer1.compareTwoModels(data[0],data[1]);
Data is an array containing the models.
I get a "viewer.compareTwoModels is not a function" error which means either there is a typo in the function name or it doesnt exist.
Without access to the extension repo, i cannot confirm this method indeed exists.
Im at loss as to what to do and will welcome any help.
EDIT:
This snippet loads the document in the viewer to display it.
Autodesk.Viewing.Document.load(`urn:${urns[index]}`, function(doc){
var viewables=doc.getRoot().getDefaultGeometry();
doc.downloadAecModelData();
viewer1.loadDocumentNode(doc, viewables, {
placementTransform: (new THREE.Matrix4()).setPosition({ x: increment, y: 0, z: 0 }),
keepCurrentModels: true,
globalOffset: { x: 0, y: 0, z: 0 }
}).then(i => {
if(urns.length > 1) {
$(viewer1.toolbar.container).find('#toolbarXLS').hide();
}
});
increment += parseInt(sessionStorage.getItem('padding1'));
});
Then, im using this to pixel compare it:
viewer1.loadModel('urn:dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLmwwLS10X0k5UkVhbnNWRXBuLXl5Zmc_dmVyc2lvbj0x', {}, (model1) => {
console.log('test load model :' + model1)
viewer1.loadModel('urn:dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLmxXX0dONUJNVDBxdDRuOGZmRWx4SkE_dmVyc2lvbj0x', {}, async (model2) => {
const pcExt = await viewer1.loadExtension('Autodesk.Viewing.PixelCompare');
pcExt.compareTwoModels(model1, model2);
console.log()
});
});
I get an instant "file extension unsupported" error, probably on the first argument the code does not reach console.log('test load model :' + model1).
The function compareTwoModels is part of the extension object, not the viewer - see PixelCompare extension
function launchViewer() {
var options = {
env: 'Local'
};
Autodesk.Viewing.Initializer(options, () => {
viewer = new Autodesk.Viewing.GuiViewer3D(
document.getElementById('forgeViewer'), {}
);
viewer.start();
// Load 2 sheets
viewer.loadModel('scissors1.pdf', {}, (model1) => {
viewer.loadModel('scissors2.pdf', {}, async (model2) => {
// Compare them
const pcExt = await viewer.loadExtension('Autodesk.Viewing.PixelCompare');
pcExt.compareTwoModels(model1, model2);
});
});
});
}

MapController and google map marker not working

So am using the google map marker in flutter, but it not working, instead it showing "Undefined name 'mapController'.
Try correcting the name to one that is defined, or defining the name"
Here is my code:
void _onMapCreated(GoogleMapController controller){
setState(() {
mapController = controller;
});
}
}
_addMarker() {
var marker = MarkerOptions(
position: mapController.cameraPosition.target,
icon: BitmapDescriptor.defaultMarker,
infoWindowText: InfoWindowText('Magic Marker', '🍄🍄🍄')
);
mapController.addMarker(marker);
}
These are the dependencies used:
geoflutterfire: "^2.0.2"
location: "^1.4.1"
google_maps_flutter: "^0.2.0"
What am I doing wrong?

Chrome extensions: How to keep badge text from flickering when navigating?

Here's a GIF demo, using a test extension.
I'm using this test extension to test out chrome.browserAction.setBadgeText(). I've noticed that when navigating, the badge text is flickering. All I am doing is clicking any hyperlinks on a webpage, so there's no page refreshing, nor navigating Back.
Is there a way to keep it from flickering? If not, is there a way to keep it persistent for as long as possible?
Code in question:
var SetBadge = function () {
chrome.windows.getCurrent({
populate: true
}, function (win) {
for (let i = 0; i < win.tabs.length; ++i) {
if (win.tabs[i].active) {
chrome.browserAction.setBadgeText({
text: "8",
tabId: win.tabs[i].id
});
}
}
});
};
chrome.webNavigation.onCommitted.addListener(() => {
SetBadge();
});
chrome.webRequest.onSendHeaders.addListener(() => {
SetBadge();
});
chrome.webRequest.onBeforeRedirect.addListener(() => {
SetBadge();
});
chrome.tabs.onActivated.addListener(() => {
SetBadge();
});
chrome.webRequest.onCompleted.addListener(() => {
SetBadge();
});

Sencha Touch - Add Markers to Map after Maprender

I want to load markers to my map, in sencha touch, after I load some json data from ajax request. The thing is I don't know how to achieve this after the maprender event is fired.
I've got this:
my map view:
app.views.MapTab = Ext.extend(Ext.Panel, {
iconCls: 'map',
id: 'map',
items: [{
xtype: 'map',
id: 'mapa',
mapOptions : {
center : new google.maps.LatLng(50.077721, 14.448585),
zoom : 12,
mapTypeId : google.maps.MapTypeId.ROADMAP,
navigationControl: true,
navigationControlOptions: {
style: google.maps.NavigationControlStyle.DEFAULT
}
},
listeners : {
'maprender' : function(comp, map){
Ext.dispatch({
controller: app.controllers.map,
action: 'map_rendered',
map: map
});
}
}
}],
initComponent: function() {
app.views.MapTab.superclass.initComponent.apply(this, arguments);
}
});
store to load json:
app.stores.results = new Ext.data.Store({
model: "app.models.Results",
proxy: {
type: 'ajax',
url: 'http://app.cz/json_list2.php?a=l&zp=1&u=vinohrady-praha&c0=500000&c1=6000000&p0=10&p1=120&cm20=1000&cm21=120000&pg=0&s=Datumu&t=byt&age=30&pod=0&lat=50.075401&lng=14.458344&pp=prodej&tp0=0&tp1=12',
reader: {
type: 'json',
root: 'markers'
}
},
listeners: {
'load': function (t, r, s) {
Ext.dispatch({
controller: app.controllers.map,
action: 'loaded',
records: r
});
}
}
});
controller
app.controllers.map = new Ext.Controller({
loaded: function(options) {
for(var i = 0; i < options.records.length; i++){
var marker = new google.maps.Marker({
position: new google.maps.LatLng(options.records[i].get('lat'), options.records[i].get('lng')),
map: app.views.mapTab.getComponent('mapa')
});
}
// need to rerender/refresh the map here
},
map_rendered: function(options) {
console.log("map rendered");
}
});
Your code should work but you are attaching the markers to the Sencha Touch Map component rather than the underlying Google Maps map, which can be accessed with the 'map' property.
...
var marker = new google.maps.Marker({
position: new google.maps.LatLng(options.records[i].get('lat'), options.records[i].get('lng')),
**map: app.views.mapTab.getComponent('mapa').map**
});
...
The map shouldn't need manually re-rendered and should just add them in when you bind them with the map config.