Select to view content in your preferred language

esriConfig.portalURL and <arcgis-map> component

83
3
yesterday
D_Atkins
Frequent Contributor

Directing applications to an Enterprise Portal can be exceptionally frustrating, as evidenced by various solved posts on here.  Using the CDN, it is relatively straightforward: just ensure the esriConfig is imported before the <body>; just like the reference doc show.

Solution example using CDN:
How to use @arcgis/map-components with ArcGIS Ente... - Esri Community


But when transitioning to ESM and using a production application bundler, the dependency tree-shaking may result in modules loading in parallel, and thus <components> still looking for arcgis.com instead of the desired portalUrl.

Solved: ArcGIS JS API Map-Componets: Load-Portal-Item not ... - Esri Community

@TJSimons 's solution -- the accepted solution -- is to import esriConfig ahead of the entry-point, but one, this solution seems too heavily abstracted for the goal of maintaining clean code, and two, the exact syntax and placement seems likely to vary between frameworks (i.e., a quick search on emulating the Angular app.config.ts in Vite is overwhelming...).

@ReneRubalcava's solution from the same thread (script in the <head> tag) -- at least in our environment -- works on a Vite/NPM dev localhost but fails after the 'build'.  Their second solution is to dynamically add the <arcgis-map> via code -- this works but feels like it defeats the purpose of the component altogether:

we've built on this idea but still find it a faff? (Or at worst, we simply don't understand the benefits relative to the 4.x pattern of defining a Map/View and assigning it to a container.)   Ultimately, for our solution, we import esriConfig, then define some asynchronous function to handle creating the map component in the DOM, and finally importing the ESRI modules...

import esriConfig from "@arcgis/core/config.js"
esriConfig.portalUrl = "yourPortalUrl"; 


// CSS Styles
import "./appStyles.css";

// Custom Modules
import * as State from    './States'
import * as Actions from  './Actions'
import * as Utils from    './utils'


async function dynamicImport(){
    import("@arcgis/map-components/components/arcgis-map");
    import("@arcgis/map-components/components/arcgis-home");
    import("@arcgis/map-components/components/arcgis-legend");
}

async function injectWebmap(){
    let mapContainer = document.getElementById("mainRight") as HTMLElement
    mapContainer.innerHTML = `
          <arcgis-map item-id="123abc456def">
            <arcgis-home    slot="top-left"></arcgis-home>
			<arcgis-legend  slot="top-right"></arcgis-legend>
          </arcgis-map>
    `
}

await injectWebmap()
await dynamicImport()

 

Aside from putting this out there for the LLM's to ingest,
 1. has anyone else encountered errors with the SDK appearing in 'build' but not 'dev'?
 2. Specifically for portalUrl, is there a cleaner or more robust solution (that is also framework-agnostic)?  

0 Kudos
3 Replies
ReneRubalcava
Esri Frequent Contributor

Do you have a small demo of this behavior?

I think import config and components in same module would cause this issue, depending on your app.

In something like React, loading config with comps should work because the render of the component happens after you probably set the config settings.

If you're app loads the components and the config and you already have <arcgis-*> elements on the page, then I can see where this could be an issue, they would get hydrated right away, maybe before your config set up is done.

Let us look at this a little further and see what can be done.

0 Kudos
D_Atkins
Frequent Contributor

I was able to recreate the error in a rather minimalistic fashion, though we did pin the issue to a particular Vite .config.

1. We used command-line with "npx @ArcGIS/create" to scaffold a Vite template.

2. Adapted the index.html:

   2a. Add the 'script type="module"' to the head with esriConfig.portalUrl.

   2b. Leave 'script=main.ts' as the application entry point.

--- So far so good, this runs in dev and after build.

 

3. We wanted a 'dashboardView.html' as a second entry point.  This naturally shares many of the basic modules written for index.html but initializes a little differently, i.e., calls a different module from the .html/body script (like "alternate.ts").

     3a. We reconfigured the build: {rollupOptions}}:

build: {
  outDir: "dist",
  rollupOptions: {
	input: {
		main:      resolve(__dirname, "index.html"),
		dashboard: resolve(__dirname, "dashboardView.html"),
	},
		
  },
},

 

This runs great in dev, but the 'build' dist version fails. So, the error we're getting can be chalked up to a very specific framework and very specific design goals. 

We're comfortable with our solution (adding map components and ESM imports via async functions) unless there's a clear and prudent reason to not use this pattern.  The question then: is there a better way?  

0 Kudos
ReneRubalcava
Esri Frequent Contributor

Thanks for that! Helps with some context.

The more I think about it, for now anyway, is don't use the item-id directly on the map/scene component.

Create the webmap first, set your config props, then assign the map to to component.

import "@arcgis/map-components/components/arcgis-map";
import config from "@arcgis/core/config.js";
import WebMap from "@arcgis/.core/WebMap.js";

config.portalUrl = "mydomain.com/arcgis";
const map = new WebMap(...);
const viewElement = document.querySelector("arcgis-map");

viewElement.map = map;

We'll think about this pattern some more. I think our current doc is more CDN focused here.

https://developers.arcgis.com/javascript/latest/authentication/access-tokens/

This sample is more about setting OAuth, but I think the same pattern would apply to setting the config props too.

https://github.com/Esri/jsapi-resources/tree/main/templates/js-maps-sdk-vite