how to import dojo modules in es6 - javascript

I'm developing a library that uses ArcGIS which based on dojo framework.
ArcGIS has main file that we include in the <script> Tag. And then we simple require their modules using require('esri/map'....
My es6 library has allot of modules and part of them need to use ArcGIS modules.
I'm using webpack and babel to bundle and transform the code. I'm not bundling ArcGIS in my library single file. I'm expecting my clients to include esri adding <script> and then include my bundle using <script>.
There I've already met an obstacle - dojo multiple define... So I've made another js excluded from the bundle that loads my bundle file using dojo require that already exist (Cause arcgis is up already and loaded dojo).
Now, the second problem I don't manage to solve is to load other ArcGIS AMD modules..
I have my class MyMap.js
export default MyMap {
constructor() {
// Adding here code to create ArcGIS Map
// this.map = new esriMap....
}
}
esriMap does not exist and must be loaded. In a simple application we would do this to make it happen
require([
"esri/Map",
"esri/views/MapView"
], function(Map, MapView) {
var map = new Map({
basemap: "streets"
});
var view = new MapView({
container: "viewDiv",
map: map,
zoom: 4,
center: [15, 65]
});
});
but this does not work.
someone ?

for using dojo's require we need simply to write window.require and it will work.
without writing window. it is failing in the build process Can't resolve 'esri/Map'
For esri users who wants to use some nice loader - check out this one
code example:
export default class myMap {
constructor(div) {
window.require(['esri/Map', 'esri/views/MapView'], (esriMap, esriMapView) => {
const map = new esriMap({
basemap: "streets"
});
const view = new esriMapView({
container: div,
map: map,
zoom: 4,
center: [15, 65]
});
});
}
}

Related

Creating a Mapboxmap with SvelteKit results in 500 Internal Error

I a trying to render a basic map with mapbox and svelte kit. The mapbox-code comes directly from this example here: https://docs.mapbox.com/help/tutorials/choropleth-studio-gl-pt-2/
I want to simply create this map in the src/lib/mapboxmap.svelte-compontent, import it into the +page-route and render it. Yet I am always getting a 500 internal error.
I think I'm simply misunderstanding something. Probably of how svelte kit works. This is the minimal mapboxmap.sveltecomponent:
<script>
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';
// define access token
mapboxgl.accessToken =
'pk.eyJ1Ijoicm9iaW5rb2hycyIsImEiOiJjanU5am95bm4xZnZ6NDNrOTRyYTYwdzJzIn0.iMFQgQIlhz36wB3819Xftw';
// create map
const map = new mapboxgl.Map({
container: 'map', // container id
style: 'mapbox://styles/examples/cjgioozof002u2sr5k7t14dim' // map style URL from Mapbox Studio
});
console.log('map: ', map);
</script>
I am then importing it into he src/routes/+page.svelte route like this:
<script>
import Mapboxmap from '../lib/mapboxmap.svelte';
</script>
<Mapboxmap />
And this is the result:
I think it might be a silly question, but I can't find the solution right now
You need to move the mapbox initialization part within an onMount block.
Otherwise, this code is run server-side and mapbox server won't like it, plus DOM being not initialized, the container 'map' does not exist yet (not to mention you actually have to insert it in your HTML block).
Something of the like will work :
<script>
import {onMount} from 'svelte'
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';
let map;
onMount(async()=>{
mapboxgl.accessToken =
'pk.eyJ1Ijoicm9iaW5rb2hycyIsImEiOiJjanU5am95bm4xZnZ6NDNrOTRyYTYwdzJzIn0.iMFQgQIlhz36wB3819Xftw';
// create map
map = new mapboxgl.Map({
container: 'map', // container id
style: 'mapbox://styles/examples/cjgioozof002u2sr5k7t14dim' // map style URL from Mapbox Studio
});
})
</script>
<div id="map">

What is the meaning of empty export {} in vanilla javascript/HTML

In the Google Maps Javascript API example, I see they had something like this in the HTML:
<script type="module" src="./index.ts"></script>
and an empty export statement at the end of the TS/JS scripts.
let map;
function initMap() {
map = new google.maps.Map(document.getElementById("map"), {
center: { lat: -34.397, lng: 150.644 },
zoom: 8,
});
}
window.initMap = initMap;
export {};
I don't see any examples or mentioning of empty exports on MDN, so I was wondering if anyone knew how it works. How does the script know to run it if the export is empty.
This looks like something in TypeScript; it has nothing to do with JavaScript.
If either of the cases below occurs, then you will need an import/export in the file.
The TypeScript file is being called with the flag below.
--isolatedModules
The tsconfig.json file has the following key and value.
{
"isolatedModules": true
}
According to typescriptlang.org, it states:
If isolatedModules is set, all implementation files must be modules (which means it has some form of import/export). An error occurs if any file isn’t a module.
If you try to run the TypeScript file with the --isolatedModules flag, you get an error like below.
'index.ts' cannot be compiled under '--isolatedModules' because it is considered a global script file. Add an import, export, or an empty 'export {}' statement to make it a module.
As the error states above, the simplest way to fix the issue without adding any unnecessary import statements and/or export statements, it is easiest to export an empty object ({}), like so.
export {};
In summary, the empty object export will not do anything in JavaScript (or TypeScript, without the --isolatedModules flag). However, it comes in handy when running with the --isolatedModules flag.
The Google Maps JavaScript API example might be getting ready for this scenario, in case someone copied-and-pasted the code, so that they wouldn't get an error.

Issues with using js interop for blazor hybrid app

When I'm trying to call a js function named initMap via interop in a hybrid blazor app, I keep getting the following error:
Could not find 'initMap' in 'window'
I have the following code:
TestApp.Windows\wwwroot\index.html
...
<head>
<script src="../js/initGoogleMap.js"></script>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=&callback=initMap"></script>
</head>
...
TestApp.Windows\wwwroot\js\initGoogleMap.js
window.initGoogleMap = {
initMap: function () {
const latLng = new google.maps.LatLng(40.716948, -74.003563);
const options = {
zoom: 14,
center: latLng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
const map = new google.maps.Map(document.getElementById("map"), options)
}
};
TestApp\WebUI\Pages\Index.razor
#page "/"
#inject IJSRuntime JSRuntime
<h1>Hello, world!</h1>
Welcome to your new app.
<div id="map" style="height:500px; width:100%;"></div>
#code{
protected override async Task OnAfterRenderAsync(bool firstRender) {
if (firstRender)
{
Console.WriteLine("first render");
await JSRuntime.InvokeVoidAsync("initMap");
}
}
}
Any ideas why this error occurs? I tried several small tweaks but to no avail. Any help would be greatly appreciated!
Try await JSRuntime.InvokeVoidAsync("initGoogleMap.initMap");
https://learn.microsoft.com/en-us/aspnet/core/blazor/javascript-interoperability/call-javascript-from-dotnet?view=aspnetcore-5.0#capture-references-to-elements
Most likely the static files are not copied in the working directory. Here are some steps to deal with the issue:
In the common project make sure all static resources are set to
"copy if newer" (in the file's properties)
In index.html file, please set the file path to match the following pattern:
"_content/<PROJECT_NAME>/path/to/the/file.js"
In your case that would be:
"_content/TestApp/js/initGoogleMap.js"
Delete all bin and obj folders in every project and rebuild whole solution.
If issue persists for Android, please Uninstall the app from the android emulator and repeat step 3.
P.S. Here's a link to the issue in Blazor Binding's repo: https://github.com/dotnet/MobileBlazorBindings/issues/211

Usage of Openlayers in Django

It's been few days i'm trying to make Openlayers work with my Django web site.
I'm totally a noob in Web, so I might miss straightforward stuff that I'm not able to understand, yet.
From what I understand, I need to load Openlayers, so for this in my index.html, I've added in the <head> this :
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io#master/en/v6.3.1/build/ol.js"></script>
Then in the <body> I've added the index.js where I would like to work with openlayers:
<script src="{% static 'index.js'%}"></script>
I've copy paste a simple example in the index.js and it's been working correctly.
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
view: new ol.View({
center: ol.proj.fromLonLat([2.333333, 48.866667]),
zoom: 10
})
});
So I have a map centered on Paris. Now I would like to load a GeoJson file, thus I need to add a Layer containing the GeoJon. For this I've followed an example here.
Here is my first problem I tried to import like this : import GeoJSON from 'ol/format/GeoJSON';
or like this import Style from ol.style.Style bit I got this error : Uncaught SyntaxError: Cannot use import statement outside a module
The only solution I found was to new ol.style.Style(...) when I needed to use it. Ugly, but working.
So I've delete all the import and used the full path of each class to call the constructors. Until one of them would not work.
var vectorLayer = new ol.layer.Vector.VectorLayer({
source: new ol.source.Vector.VectorSource({
url: 'data/geojson/countries.geojson',
format: new ol.format.GeoJSON()
}),
style: function(feature) {
style.getText().setText(feature.get('name'));
return style;
}
});
Uncaught TypeError: ol.source.Vector.VectorSource is not a constructor
https://openlayers.org/en/latest/apidoc/module-ol_source_Vector-VectorSource.html
So I'm asking my self why it is not working, and how is it possible to make it less ugly (to use the Imports)
var vectorLayer = new ol.layer.Vector({
source: new ol.source.Vector({
You can check the OpenLayers 4 examples https://openlayers.org/en/v4.6.5/examples/ for full build syntax

How to limit map display in Vue-Leaflet to specific boundary using leaflet plugin (without vue2 wrapper)

I am developing a simple Vue application to act as a repository for all things corona-virus in my country. I want to show a map using Vue2-leaflet but i want only my country to appear such as this example, its exactly what I want but its built using vanilla leaflet using leaflet-boundary-canvas which is a leaflet plugin.
I want to basically replicate this example but built using vue2-leaflet
this is my repo
In short:
added leaflet-boundary-canvas package
imported both 'leaflet' and 'leaflet-boundary-canvas' in map.vue and,
...because there is no vue2- wrapper for leaflet-boundary-canvas leaflet plugin, I used the plugin directly on the mapObject, in mounted() of map.vue:
import 'leaflet';
import 'leaflet-boundary-canvas';`
....
mounted() {
this.$nextTick(() => {
const map = this.$refs.map.mapObject;
window.L.TileLayer.boundaryCanvas(
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
{ boundary: this.bwGeoJson.features[0] }
).addTo(map);
})
}
...
... where this.$refs.map is the <l-map>, and this.bwGeoJson.features[0] is the GeoJSON.Polygon of the boundary.
Here's the PR on your repo, here's the list of changes and here's a screenshot with the result:

Categories

Resources