Map not displaying with Leaflet - javascript

I am completely new to developing applications that bring in maps. I am developing a mobile application using Apache Cordova, Javascript, HTML5, and Leaflet. On the index.html page, I need to display a map on the page. I have a DIV on the page for the map but the map does not display. I have tried it in a few different emulators with no luck. I have made sure that the img-src attribute allows for images to be pulled in from the correct resource. I have also tried a few different free providers. Lastly, I moved the javascript code from the bottom of the index.html file to the onDeviceReady() handler in the index.js file. My code for the two files are below. Can anyone tell why my map isn't showing? I have followed the examples I viewed and it looks fine from what I can tell, but that doesn't mean a thing. Any help would be greatly appreciated. Thanks.
index.js file:
// For an introduction to the Blank template, see the following documentation:
// http://go.microsoft.com/fwlink/?LinkID=397704
// To debug code on page load in Ripple or on Android devices/emulators: launch your app, set breakpoints,
// and then run "window.location.reload()" in the JavaScript Console.
(function () {
"use strict";
document.addEventListener( 'deviceready', onDeviceReady.bind( this ), false );
function onDeviceReady() {
// Handle the Cordova pause and resume events
document.addEventListener( 'pause', onPause.bind( this ), false );
document.addEventListener( 'resume', onResume.bind( this ), false );
// TODO: Cordova has been loaded. Perform any initialization that requires Cordova here.
//var element = document.getElementById("deviceready");
//element.innerHTML = 'Device Ready';
//element.className += ' ready';
var myMap = L.map('map').setView([38.92940492128304, -94.66508077838485], 13);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
{
attribution: '© OpenStreetMap',
maxZoom: 19
}).addTo(myMap);
//L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
// attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox',
// maxZoop: 18,
// id: 'your.mapbox.project.id',
// accessToken: 'your.mapbox.public.access.token'
//}).addTo(myMap);
};
function onPause() {
// TODO: This application has been suspended. Save application state here.
};
function onResume() {
// TODO: This application has been reactivated. Restore application state here.
};
} )();
index.html file:
<!DOCTYPE html>
<html>
<head>
<!--
Customize the content security policy in the meta tag below as needed. Add 'unsafe-inline' to default-src to enable inline JavaScript.
For details, see http://go.microsoft.com/fwlink/?LinkID=617521
-->
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-inline'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; media-src *; font-src 'self' https://fonts.gstatic.com; script-src 'self' 'unsafe-inline'; img-src 'self' data: *.tile.openstreetmap.org *.openstreetmap.org">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
<link rel="stylesheet" type="text/css" href="css/index.css">
<link rel="stylesheet" type="text/css" href="css/leaflet.css" />
<link rel="stylesheet" type="text/css" href="css/bootstrap-cyborg.css" />
<title>MockupsForLis</title>
</head>
<body>
<div class="header">
...
</div>
<div id="map"></div>
<footer>
...
</footer>
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="scripts/platformOverrides.js"></script>
<script type="text/javascript" src="scripts/index.js"></script>
<script type="text/javascript" src="scripts/leaflet-src.js"></script>
<script src="scripts/jquery-2.2.2.min.js"></script>
<script src="scripts/bootstrap.js"></script>
</body>
</html>

In light of mattesCZ's comment above, I decided to change the height defined on the map DIV from a percentage to pixels and the map displayed with no problem at all.

Related

Serving SvelteKit app through VSCode Webview API

This question is being asked after spending weeks and giving up multiple times on trying to solve this.
I'm developing a VSCode extension that needs to make use of the Webview API. For a while, this could be using Svelte, but now with SvelteKit released as stable and being treated as default when you do npm create svelte, I targetted to use that. After configuring the app to be static SPA with SSR turned off and using the #sveltejs/adapter-static, it seems that serving it is not the same as it was with vanilla Svelte.
This is the svelte.config.js:
import adapter from '#sveltejs/adapter-static';
import preprocess from 'svelte-preprocess';
/**
* Consult https://github.com/sveltejs/svelte-preprocess
* for more information about preprocessors
*
* #type {import('#sveltejs/kit').Config} */
export default {
preprocess: preprocess(),
kit: {
adapter: adapter({ fallback: 'index.html' }),
// ssr: false, // deprecated
csp: {
directives: {
'default-src': ['none'],
'img-src': ['{{cspSource}} https:'],
'script-src': ['{{cspSource}}'],
'style-src': ['{{cspSource}}'],
},
},
// paths: {
// base: '{{baseURL}}', // not accepted
// },
},
};
This is the built HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="/favicon.png" />
<meta name="viewport" content="width=device-width" />
<meta http-equiv="content-security-policy" content="default-src 'none'; img-src {{cspSource}} https:; script-src {{cspSource}} 'sha256-N2DRY+AREasGSTE5X4BdHoEYZsaGOpTvUwTBIHmryVA='; style-src {{cspSource}}">
<link rel="modulepreload" href="/_app/immutable/start-e16b6a0f.js">
<link rel="modulepreload" href="/_app/immutable/chunks/index-0576dc7c.js">
<link rel="modulepreload" href="/_app/immutable/chunks/singletons-51070258.js">
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">
<script type="module" data-sveltekit-hydrate="45h">
import { start } from "/_app/immutable/start-e16b6a0f.js";
start({
env: {},
paths: {"base":"","assets":""},
target: document.querySelector('[data-sveltekit-hydrate="45h"]').parentNode,
version: "1672682689612"
});
</script></div>
</body>
</html>
Contrary to vanilla Svelte that would generate something like:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="/favicon.png" />
<meta name="viewport" content="width=device-width" />
<script src="/dist/app/main.js"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
That could be served through Webview like:
function getWebviewContent(webview, context) {
return `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta
http-equiv="Content-Security-Policy"
content="${[
"default-src 'none'",
`img-src ${webview.cspSource} https:`,
`script-src ${webview.cspSource}`,
`style-src ${webview.cspSource}`,
].join(';')};"
/>
<title>My Extension</title>
<script type="module" crossorigin src="${webview.asWebviewUri(
vscode.Uri.joinPath(context.extensionUri, 'dist/app/main.js')
)}"></script>
<link rel="stylesheet" href="${webview.asWebviewUri(
vscode.Uri.joinPath(context.extensionUri, 'dist/app/style.css')
)}">
</head>
<body><div id="app"></div></body>
</html>
`;
}
The file is bit more complex now, so I can't (and shouldn't) try to rewrite it in this function.
The following are the conditions:
VSCode needs absolute paths since it has different environments and protocols. Keep in mind that an extension is served locally to every user. (context.extensionUri is IMPORTANT)
SvelteKit has its set of configurations (different from Vite) that may pose to be restrictive specially with SPA mode.
Content Security Policy for Webview is also restrictive to what and what can't be used.
Probably due to Vite, the file names have hashes, so it's not consistent - but I'm preferring to keep that.
The script block in the HTML (may also need a nonce) is importing the start function relatively as a module.
Instead of writing another template as a string for VSCode that would need to be maintained, it would be ideal to have the generated HTML read into VSCode and served. Using Mustache seems good (hence you see {{cspSource}} in the HTML above).
How would one suggest to architecture and integrate this?

StencilJS + Facebook Instant Game, app-root not rendering

I am trying to set up my facebook instant game.
I have followed https://developers.facebook.com/docs/games/instant-games/test-publish-share , to test locally then deploy into production.
When testing, everything works fine. However, in production, nothing shows up (black screen) when I open my game. <app-root> doesn't render, app-home's constructor isn't called and it takes up 0x0 pixels.
This is my index.html
<!--
Copyright (c) 2017-present, Facebook, Inc.
All rights reserved.
This source code is licensed under the license found in the
LICENSE file in the root directory of this source tree.
-->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="full-screen" content="yes" />
<meta name="screen-orientation" content="portrait" />
<meta name="viewport" content="user-scalable=no" />
<script type="module" src="/build/app.esm.js"></script>
<script nomodule src="/build/app.js"></script>
<link href="/build/app.css" rel="stylesheet">
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icon/apple-touch-icon.png">
<link rel="icon" type="image/x-icon" href="/assets/icon/favicon.ico">
<link rel="manifest" href="/manifest.json">
</head>
<body>
<script src="https://connect.facebook.net/en_US/fbinstant.6.2.js"></script>
<script type="text/javascript">
const assets = [
'img/asset1.png',
'img/asset2.png',
'img/asset3.png',
'img/asset4.png'
];
window.onload = function () {
// When the window loads, start to initialize the SDK
FBInstant.initializeAsync().then(function () {
// We can start to load assets
for (let i in assets) {
// When preloading assets, make sure to report the progress
FBInstant.setLoadingProgress(i / assets.length * 100);
}
// Now that assets are loaded, call startGameAsync
FBInstant.startGameAsync().then(() => console.log("initialized"));
});
};
</script>
<app-root></app-root>
</body>
</html>
'initialized' is printed in the console, when I open the game. There are two errors there with it (which might have to do with the error I am having)
Console logs
The 404 error (resource not found) is a .js file which I checked was included in the .zip file which I uploaded.
This is what i see when I inspect element on the game
Inspect element
Also, on mobile, nothing is displayed (white screen)
Any help would be greatly appreciated.
Thanks! :)

javascript code from external file can not be executed in Cordova app

I want to load an external javascript (without jquery or others) into my Corodova/Phonegapp app (Visual Studio 2015, Cordova CLI 6.1.1) when the app is actually ready and online (I check that in the original code, but did not enter it in the example below). Ultimately this external javascript will be the google maps javascript api. However since I ran into some problems I first tryed with my own little javascript file (external_file.js).
While debugging I can see that the <script src="https://myhost/external_file.js"></script> tag is writen into the original code of my app, but I can not access the loaded code (function external_function() is not available ). I tryed with the ripple emulator as well as with my android 5.1.1 device.
All my functions work on a "normal" html file without cordova. Also when I try to load the javascript file locally (from scripts/external_file.js) I can access the functions located inside the file.
I search quite some time for a solution, but did not find anything usefull:
Andreas Linnert had a similar problem in 2013, but no answer is given there.
psycrow117 wanted to load the googel maps api with <script></script> tags (as given in the Google Maps Javascript API Example). However I would like to do that with a function
rolinger did not load the cordova-plugin-whitelist (which I do)
FabianE and KRIZTE describe the same problem. I actually use the solution by Blauharley and e-satis with Jason Livesay to load the external script. However the problem does not seem to be solved in that post, too.
I know that there is the cordova-plugin-googlemaps to load the native environment. Let's just say I do not want to do that for now. If there is no other solution I will have to...
Since my functions work with a "normal" html file and I can also load a local script file corretly, I think I forgot to set something correctly to be able to execute the external code.
I set the Content-Security-Policy to
<meta http-equiv="Content-Security-Policy" content="default-src: 'self' https://myhost https://maps.google.com 'unsafe-inline' 'unsafe-eval'">
<meta http-equiv="Content-Security-Policy" content="script-src: 'self' https://myhost https://maps.google.com 'unsafe-inline' 'unsafe-eval'">
I also entered the cordova-plugin-whitelist parameters
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<access origin="https://*.googleapis.com" />
<access origin="https://myhost" />
<access origin="*" />
<allow-navigation href="https://*.googleapis.com" />
<allow-navigation href="https://myhost" />
<allow-navigation href="*" />
<allow-intent href="https://*.googleapis.com" />
<allow-intent href="https://myhost" />
<allow-intent href="*" />
But somehow that does not seem to work, too.
Does anyone have a solution to be able to execute the code after loading the external file?
Later the google maps javascript api needs to be asyncron, but that's a nother issue then.
index.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
<!-- Enable all requests, inline styles, and eval() -->
<meta http-equiv="Content-Security-Policy" content="default-src: 'self' https://myhost https://maps.google.com 'unsafe-inline' 'unsafe-eval'">
<meta http-equiv="Content-Security-Policy" content="script-src: 'self' https://myhost https://maps.google.com 'unsafe-inline' 'unsafe-eval'">
<link rel="stylesheet" type="text/css" href="css/index.css">
<title>Testapp</title>
</head>
<body>
<div class="app">
<h1>Testapp</h1>
<button id="loadexternal_button">load external file</button>
<button id="isloaded_button">is loaded?</button>
<div id="map"></div>
</div>
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="scripts/platformOverrides.js"></script>
<script type="text/javascript" src="scripts/index.js"></script>
</body>
</html>
index.css
.app {
background-color:white;
}
#map{
height: 400px;
width: 400px;
border:1px solid white;
}
index.js
(function () {
"use strict";
function onDeviceReady() {
// Event Listener for Buttons: https://stackoverflow.com/a/31892530/2381164
document.getElementById('isloaded_button').addEventListener('click', function () { checkLoadedFile(); }, false);
document.getElementById('loadexternal_button').addEventListener('click', function () { loadJS('https://myhost/external_file.js', hasloaded(), document.body);
}, false);
};
// https://stackoverflow.com/a/950146/2381164
function loadJS(url, implementationCode, location) {
var scriptTag = document.createElement('script');
scriptTag.src = url;
scriptTag.onload = implementationCode;
scriptTag.onreadystatechange = implementationCode;
location.appendChild(scriptTag);
};
// Change color of div when script is loaded
function hasloaded() {
var mapElement = document.getElementById('map');
mapElement.setAttribute('style', 'border:1px solid yellow');
}
// Change background-color of div when file is loaded propperly
function checkLoadedFile() {
var mapElement = document.getElementById('map');
if (typeof external_function === 'function') {
mapElement.setAttribute('style', 'background-color: green;');
} else {
mapElement.setAttribute('style', 'background-color: red;');
}
}
// Load when App is ready
document.addEventListener('deviceready', onDeviceReady.bind(this), false);
})();
external_file.js
function external_function() {
var mapElement = document.getElementById('map');
mapElement.setAttribute('style', 'background-color: orange;');
}
This is the security policy meta i am currently using:
<meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval; media-src *">
It currently accepts everything I throw at it! ...please keep in mind that using
content="default-src *;
is not 100% safe as it will run scripts from any location (local or online), but as long as you have
script-src 'self'
in your security meta... the problems you are currently facing while executing external scripts should be a thing of the past!

Loading Google Map Api using $.getScript on a Ionic app

I'm currently working on web-app using apache cordova, ionic and google map.
I'm getting issues trying to load correctly the google map js api. The problem is that the app don't work on my device but works just fine when I emulate it on Ripple.
So I have a controller for a Ionic View, when the user enter this view a condition check if the google maps api is loaded, if not we load it and then start using the GM Api. I can't figure where it has gone wrong.
Here is the condition making the call for the loading function...
$scope.$on('$ionicView.loaded', function () {
var test = false;
if (test) {
alert("Google Map api fully loaded");
}
else {
alert("Google map api not loaded"); //The alert is fired.
$scope.loadApi();
}
});
The loading function
$scope.loadApi = function () {
if ($cordovaNetwork.isOnline()) //check if device is connected {
alert('Loading api'); //The alert is fired
$.getScript('https://maps.googleapis.com/maps/api/js?sensor=false&key=xxx',
function () {
alert("Api Loaded"); //Alert not fired on device
$scope.startGeo(); // The function isn't called so no map
});
}
else {
alert('Check your connexion');
}
};
Here is the html part, in case I forgot something....
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<title></title>
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above
<link href="css/ionic.app.css" rel="stylesheet">
-->
<!-- ionic/angularjs js -->
<script src="lib/ionic/js/ionic.bundle.js"></script>
<!--Google map for Angular-->
<script src="lib/angular-google-maps/lodash.min.js"></script>
<script src="lib/angular-google-maps/angular-simple-logger.min.js"></script>
<script src="lib/angular-google-maps/angular-google-maps.min.js"></script>
<script src="lib/localforage/localforage.min.js"></script>
<script src="lib/localforage/angular-localForage.min.js"></script>
<script src="lib/jquery.js"></script>
<script src="lib/ngCordova/dist/ng-cordova.min.js"></script>
<!-- cordova script (this will be a 404 during development) -->
<script src="cordova.js"></script>
<!-- your app's js -->
<script src="js/app.js"></script>
<!--<script src='https://maps.googleapis.com/maps/api/js?sensor=false&key=xxx'></script>-->
<script src="js/controllers.js"></script>
</head>
<body ng-app="myapp">
<ion-nav-view></ion-nav-view>
</body>
</html>
I've tried many things such as using angular-load, replacing the getScript function by an ajax call (that is basically just the same thing), tried this answer to see if it could help..
Thanks for your help.
FIRST SOLUTION
Solved my problem by replacing the Google Map loading links.
index.html
Installed the whitelist plugin and added in the head :
<meta http-equiv="Content-Security-Policy" content="default-src *; script-src 'self' 'unsafe-inline' 'unsafe-eval' *; style-src 'self' 'unsafe-inline' *">
Replaced google Map loading link :
<script src='//maps.googleapis.com/maps/api/js?sensor=false'></script>
Got rid of the https: from the link.
controller.js
In the map's controller :
The loading function, I replaced the https protocol by the http one.
$scope.loadApi = function () {
if ($cordovaNetwork.isOnline()) {
console.log($scope.logs.apiLoading);
$.getScript('http://maps.googleapis.com/maps/api/js?sensor=false', function () {
$scope.startGeo();
});
}
else if($cordovaNetwork.isOffline()) {
alert($scope.logs.deviceOffline);
}
};
SECOND SOLUTION (Using angular-google-maps)
Just a reminder of angular google map's config in the app.js
For those using Angular google Map. The library load google map automatically, you just have to set it up properly. There is also an event to check if the google map is loaded. I wasn't aware of this at the time, and mixed everything, angular google maps loading process with mine. etcetera :)
angular.module('myapp').config(function (uiGmapGoogleMapApiProvider) {
uiGmapGoogleMapApiProvider.configure({
key: 'myKey',
v: '3.20', //defaults to latest 3.X anyhow
libraries: 'weather,geometry,visualization,places'
});
})

Getting a 'google is not defined' error when trying to use google.maps.geocoder in Android app

I have an ionic cordova Android app where I am trying to use the Google maps API. Specifically I want to use the geocoder feature. In my Cordova Android app code I have a line of code to get access to the geocoder:
var geocoder = new google.maps.Geocoder();
This line of code is in the ''file and is throwing an error: 'ReferenceError google is not defined'.
I am adding the google maps api in the index.html file as follows:
<!DOCTYPE html>
<html ng-csp="">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<meta http-equiv="Content-Security-Policy"
content="default-src *;
script-src 'self' 'unsafe-inline' 'unsafe-eval'
127.0.0.1:*
http://192.168.1.254
maps.googleapis.com
autolinkmaker.itune.apple.com
http://*.itunes.apple.com
http://*.googleapis.com
http://*.maxplatform.com
https://*.itunes.apple.com
https://*.googleapis.com
https://*.maxplatform.com
;
style-src 'self' 'unsafe-inline'
127.0.0.1:*
http://192.168.1.254
maps.googleapis.com
autolinkmaker.itune.apple.com
http://*.itunes.apple.com
http://*.googleapis.com
http://*.maxplatform.com
https://*.itunes.apple.com
https://*.googleapis.com
https://*.maxplatform.com
">
<title></title>
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Open%20Sans%3A300%2C600%2C700" rel="stylesheet" type="text/css">
<!-- ionic/angularjs js -->
<script src="lib/ionic/js/ionic.bundle.js"></script>
<script src="js/ng-cordova.min.js"></script>
<script src="js/parse-1.6.7.min.js"></script>
<!-- cordova script (this will be a 404 during development) -->
<script src="cordova.js"></script>
<script src="js/app.js"></script>
<script src="js/controllers/appctrl.js"></script>
<script src="js/controllers/sharectrl.js"></script>
<script src="js/controllers/homectrl.js"></script>
<script src="js/controllers/tourctrl.js"></script>
<script src="js/controllers/newsctrl.js"></script>
<script src="js/controllers/friendsctrl.js"></script>
<script src="js/controllers/discoverctrl.js"></script>
<script src="js/controllers/watchlistctrl.js"></script>
<script src="js/controllers/trailerctrl.js"></script>
<script src="js/controllers/settingsctrl.js"></script>
<script src="lib/angular-base64/angular-base64.min.js"></script>
<script src="lib/angular-resource/angular-resource.min.js"></script>
<script src="lib/angular-animate/angular-animate.min.js"></script>
<script src="lib/angular-messages/angular-messages.min.js"></script>
<script src="lib/ionic-rating/ionic-rating.min.js"></script>
<script src="lib/ion-google-place/ion-google-place.js"></script>
<script src="http://maps.googleapis.com/maps/api/js?libraries=places&sensor=false"></script>
</head>
<body ng-app="cuesApp" ng-cloak="">
<ion-nav-view>
</ion-nav-view>
</body>
</html>
I can't see why google is undefined?
You are loading the Google Maps API after all your other scripts, so when you try to use google.maps it doesn't exist yet.
Move <script src="http://maps.googleapis.com/maps/api/js?libraries=places&sensor=false"></script> to the top to fix it.
Look for the meta security tag. and debug the ionic app using chrome://inspect/#devices in the chrome browser. You will notice the meta security errors.

Categories

Resources