Automatically switch basemap at zoomlevel? - javascript

I am trying to make leaflet change the basemap depending on the zoomlevel. What I am trying:
(I am new to coding)
I am receiving an error statement:
SyntaxError: missing ) after argument list
I did check the syntax several time but cant find the error.
I also wonder if there is a more elegant way to write it, instead of that double if-else statement.
map.addEventListener("zoomend", changeBasemap);
function changeBasemap() {
var zoomLevel = map.getZoom();
if (zoomLevel < 5) {
if (map.hasLayer(osm)) {
map.removeLayer(osm);
stamen_Watercolor.addTo(map);
} else {
console.log(no need to change basemap)
}
} else {
if (map.hasLayer(stamen_Watercolor)) {
map.removeLayer(stamen_Watercolor);
osm.addTo(map);
} else {
console.log(no need to change basemap);
}
}
}

The error is because you forgot quotes in:
console.log(no need to change basemap);
Correct it to:
console.log("no need to change basemap");
Here's a suggestion about how your code could look cleaner:
function changeBasemap()
{
if ( map.getZoom() < 5 && map.hasLayer(osm) ) {
map.removeLayer(osm);
stamen_Watercolor.addTo(map);
return;
}
if ( map.getZoom() > 4 && map.hasLayer(stamen_Watercolor) ) {
map.removeLayer(stamen_Watercolor);
osm.addTo(map);
return;
}
console.log("no need to change basemap");
}

Related

Having problems with Javascript Else If statement in Node Red

I have been fighting this problem all day. Heres a snippet of my code, 5 lines down in the else if is where things get screwy. I am also new to Javascript so that may be the reason I am unable to spot the mistake, but from what I have seen elsewhere, this code should work. Also the comments on lines 5 and 6 are swapped.
if (msg.payload.License_Plate !== null) {
// This portion checks for a valid number plate
if (readlpr == dblpr); { // we have a direct match, open the gate
opengate = 1; // will send open signal to gpio
} else if(readlpr !== null); { // from here on, we are checking for a partial plate match
validdigits = 0; // make sure we have data before continuing, as may be a rfid match
{
if (!context.count); { // check to see if counter already used, if not initialise it
context.count = 0;
Image of error message
You have a few errors:
if (readlpr == dblpr); {
...
} else if(readlpr !== null); {
...
if (!context.count); {
And also an extra opening-brace.
These shouldn't have a semi colon on the end:
if (readlpr == dblpr) {
...
} else if(readlpr !== null) {
...
if (!context.count) {
In the end it should look something like this:
if (msg.payload.License_Plate !== null) {
if (readlpr == dblpr) {
opengate = 1;
} else if(readlpr !== null) {
validdigits = 0;
// { <!-- Remove this as well, it's an extra brace
if (!context.count) {
context.count = 0;

Is there a better way to 'do nothing' in javascript if statement?

My url looks like this = https://studentscafe.com/menu/2
I'm trying to check whether or not it has 2 different url params...
1.) ?dinner=1
or
2.) &dinner=1
If #1 is present, do nothing
If #2 is present, do nothing
But if neither are present, default to adding ?dinner=1 to the url.
Is there a better way to have a default do nothing in an if statement? Fiddle here for example.
var path = 'https://studentscafe.com/menu/2';
if (path.indexOf('?dinner=1') >= 1) {
console.log('has ?');
// do nothing leave url as it is
} else {
console.log('does not have ?');
if (path.indexOf('&dinner=1') >= 1) {
// do nothing leave url as it is
} else {
path = path + '?dinner=1';
}
}
Expected output: if the url doesn't have #1 or #2: https://studentscafe.com/menu/2?dinner=1
Instead of
if (something) {
// do nothing
} else {
// do what you need
}
You can use
if (!something) {
// do what you need
}
In your case:
if (path.indexOf('?dinner=1') == -1 && path.indexOf('&dinner=1') == -1) {
path = path + '?dinner=1';
}
Using a regular expression and the ! negation operator, this can be rather simple:
var path = 'https://studentscafe.com/menu/2';
if (!/[?&]dinner=1/.test(path)) {
path += '?dinner=1';
}
console.log(path);
You can do this way.
var path = 'https://studentscafe.com/menu/2';
// Since there is no change to path if it contains either ?dinner=1 or &dinner=1
if (path.indexOf('dinner=1') >= 1) {
console.log('has dinner');
// do nothing leave url as it is
} else {
path = path + '?dinner=1';
}
In modern JS you may simply do like
['?dinner=1','?dinner=2'].every(s => !path.includes(s)) && (path += '?dinner=1');

Unexpected token operator «=», expected punc «,»

i am getting the following error
Parse error: Unexpected token operator «=», expected punc «,» Line
159, column 26
This is my code
function fitBounds(type="all", shape=null) {
var bounds = new google.maps.LatLngBounds();
if ( type == "all" ){
if ((circles.length > 0) | (polygons.length > 0)){
$.each(circles, function(index, circle){
bounds.union(circle.getBounds());
});
$.each(polygons, function(index, polygon){
polygon.getPath().getArray().forEach(function(latLng){
bounds.extend(latLng);
});
});
}
}
else if ( (type == "single") && (shape != null) ) {
if (shape.type == google.maps.drawing.OverlayType.MARKER) {
marker_index = markers.indexOf(shape);
bounds.union(circles[marker_index].getBounds());
}
else {
shape.getPath().getArray().forEach(function(latLng){
bounds.extend(latLng);
});
}
}
if (bounds.isEmpty() != true)
{
map.fitBounds(bounds);
}
}
You are trying to use Default parameters, which are a bleeding edge feature of JavaScript with limited support.
JS Lint rejects them unless you turn on the ES6 option.
#Quentin is exactly right: You need the es6 option.
There's lots more that fails JSLint, however, particularly your use of ==, which is a "coercing operator" -- check JSLint on equality -- and the bitwise option in the jslint section (there's no link directly to jslint directives, I don't think, so I linked just above it). As #AxelH suggests, there's likely more you really want to ask us. ;^)
Here's a version that lints on JSLint.com as it stands today. Note the /*jslint directive line at the top that includes the es6 tag:
/*jslint es6, white, browser */
/*global google, $ */
// These weren't declared, so I'm assuming they're
// within scope in your snippet's context.
// I put others that felt like globals (google, $)
// into globals, above.
var marker_index;
var markers;
var circles;
var polygons;
var map;
function fitBounds(type="all", shape=null) {
var bounds = new google.maps.LatLngBounds();
if ( type === "all" ){
// not sure why you're using bitwise `|` here.
// I think this'll be equivalent, though you should
// be able to set `bitwise` as an option if it's not.
// Still, you're evaluating to booleans, so `|` doesn't
// seem appropriate here.
if ((circles.length > 0) || (polygons.length > 0)){
$.each(circles, function(ignore, circle){
bounds.union(circle.getBounds());
});
$.each(polygons, function(ignore, polygon){
polygon.getPath().getArray().forEach(function(latLng){
bounds.extend(latLng);
});
});
}
}
else if ( (type === "single") && (shape !== null) ) {
if (shape.type === google.maps.drawing.OverlayType.MARKER) {
marker_index = markers.indexOf(shape);
bounds.union(circles[marker_index].getBounds());
}
else {
shape.getPath().getArray().forEach(function(latLng){
bounds.extend(latLng);
});
}
}
if (!bounds.isEmpty())
{
map.fitBounds(bounds);
}
}
#Quentin is right with his answer. You get syntax error due to reasons that he mentioned. What I can add to it is that you might try to drop EC6 syntax, and rewrite your function to old good JS.
// change from
function fitBounds(type="all", shape=null)
// change to
function fitBounds(type="all", shape)
A workaround to this issue could be this:
function fitBounds(type, shape_aux) {
var bounds = new google.maps.LatLngBounds();
if(typeof type === "undefined") {
type = "all";
}
if(typeof shape_aux !== undefined) {
shape = shape_aux;
} else {
shape = null;
}
if ( type == "all" ){
if ((circles.length > 0) | (polygons.length > 0)){
$.each(circles, function(index, circle){
bounds.union(circle.getBounds());
});
$.each(polygons, function(index, polygon){
polygon.getPath().getArray().forEach(function(latLng){
bounds.extend(latLng);
});
});
}
}
else if ( (type == "single") && (shape != null) ) {
if (shape.type == google.maps.drawing.OverlayType.MARKER) {
marker_index = markers.indexOf(shape);
bounds.union(circles[marker_index].getBounds());
}
else {
shape.getPath().getArray().forEach(function(latLng){
bounds.extend(latLng);
});
}
}
if (bounds.isEmpty() != true)
{
map.fitBounds(bounds);
}
}

IE - "Error: Object doesn't support this action"

I'm getting a frustrating javascript error in IE7 that I can't get around. It is working fine in Chrome and Firefox, but not in IE..
The line I am getting the error in is: item = listGetAt(list,'1','-');
This is calling the following custom method:
function listGetAt(list,position,delimiter) {
if(delimiter == null) { delimiter = '-'; }
list = list.split(delimiter);
if(list.length > position) {
return list[position];
} else {
return list.length;
}
}
Can anyone see something I can't?
Many thanks in advance for any help.
Jason
Poor code
Why pass a string as a numeric parameter?
I would consider
function listGetAt(list,position,delimiter) {
delimiter = delimiter || '-';
if (list.indexOf(delimiter) ==-1) return -1;
list = list.split(delimiter);
return list.length>=position?list[position]:null;
}

Javascript switch statement with wildcard?

If my javascript ajaxes away to my server and returns an ID of 49 in the plain text format of [49] is there a way in which i an do something like this... (i have tested and doesnt work)
switch(data)
{
case '[*]':
(..etc.)
break;
}
Where the wildcard is the * and i want to make sure it is enclosed within two square parenthesis?
Because i need to check that there wasnt another word returned like error and i am reserving the default for unexpected errors, any ideas? :) Thanks!
You can do a switch on true explicitely, which will use evaluation on each case statement.
switch (true) {
case ((/^\[\d+\]$/).test(data)):
//matches data;
break;
case (data == "something else"):
//...
break;
default:
//...
}
However, if you have less than say 4-5 cases, it would be better to use if/else if/else if/else blocks.
if ((/^\[\d+\]$/).test(data)) {
//matches data;
} else if (data == "something else") {
//...
} else {
//...
}
I usually do some error trapping in my response methods for service/rest calls so that I almost always return a proper json with an error property if there is an error.
try {
if (response.responseText.indexOf("<html") >= 0) {
throw response.responseText;
}
var data = JSON.parse(response.responseText);
if (data.error)
throw data.error;
//handle response data object.
if ((/^\[\d+\]$/).test(data)) {
//matches data;
} else if (data == "something else") {
//...
} else {
//...
}
} catch(err) {
if (err && err.message) {
//use err.message
} else if (err && err.toString().indexOf("<html") >= 0) {
//handle error text
}
}
You could create a list of patterns and associated callbacks and do a simple loop and check for matches. For example:
var patterns = [];
function myCallback(){ document.write('myCallback!'); }
function myOtherCallback(){ document.write('myOtherCallback!'); }
function myLastCallback(){ document.write('You will never see me!'); }
patterns.push({'pattern':new RegExp(/\[.+\]/),'callback': myCallback});
patterns.push({'pattern':new RegExp(/.+/),'callback':myOtherCallback});
patterns.push({'pattern':new RegExp(/A-Z{3}/),'callback':myLastCallback});
var f = "[49]";
for(var i=0;i<patterns.length;i++){
if(patterns[i].pattern.test(f)){
patterns[i].callback();
}
}
Which outputs the following:
myCallback!myOtherCallback!
You could try to use if else and regex for matching wildcard patterns.
Assuming data = "[49]"; or any digits inside brackets.
if(/\[\d+\]/.test(data)){
//do something
}else{
//default
}
Short answer: No, switch/case can't handle wildcard.
You should probably do some preprocessing/sanity checking before entering the switch, or simply discard it completely since it's more appropriate for specific case scenarios rather than processing streamlined data. Regexp will serve you better here.

Categories

Resources