Esri / esri-loader

A tiny library to help load ArcGIS API for JavaScript modules in non-Dojo applications
Apache License 2.0
458 stars 79 forks source link

Angular5 + CLI + API 3.23 Module not found: #95

Closed dimpyvirk closed 6 years ago

dimpyvirk commented 6 years ago

Hello @ALL

I am using Angular 5 CLI and JS API 3.23. I want to use us Map object as

import Map = require('esri/map');

But getting following error Module not found: Error: Can't resolve 'esri/map'

Here is the Map component

import { Component, OnInit, ViewChild, ElementRef, Input, Output, EventEmitter } from '@angular/core'; import { loadModules } from 'esri-loader'; import Map = require('esri/map'); import Search = require('esri/dijit/Search');

@Component({ selector: 'app-esri-map', templateUrl: './esri-map.component.html', styleUrls: ['./esri-map.component.css'] })

export class EsriMapComponent implements OnInit {

constructor(private elRef: ElementRef) { }

public ngOnInit() { let map = new Map(this.elRef.nativeElement, { center: [-118, 34.5], zoom: 8, basemap: 'streets' });
} }

If I use the following code on ngOnInit and comment the import map line then it works fine

const options = { url: 'https://js.arcgis.com/3.23/' }; loadModules(['esri/map'], options) .then(([Map]) => { // create map with the given options at a DOM node w/ id 'mapNode' let map = new Map(this.elRef.nativeElement, { center: [-118, 34.5], zoom: 8, basemap: 'streets' }); }) .catch(err => { // handle any script or module loading errors console.error(err); });

Thanks In advance

tomwayson commented 6 years ago

@dimpyvirk may I ask why you are trying to import Map = require('esri/map');? Typically you use esri-loader instead of import statements for esri modules.

andygup commented 6 years ago

@dimpyvirk As an example of the pattern @tomwayson is referring to you might want to check out this repo: https://github.com/Esri/angular-cli-esri-map

dimpyvirk commented 6 years ago

@tomwayson I have an existing code using angular 2, API 3.18 and webpack. It is working fine with import. import Map = require('esri/map'); Now we are migrating it to angular 5 and CLI. I am using map service (map.service.ts) which any component call and get the map (by providing dom) and all the map related functions are there. Here is the starting part of it

createAvlMap(domNodeOrId: any) {

let mp = new Map(domNodeOrId, this.mapOptions);

let baseObj = { id: '1', title: 'Base Map' }; let base = new ArcGISTiledMapServiceLayer(localStorage.getItem('BaseMap'), baseObj);

let roadsObj = { id: '2', title: 'Roads' }; let roads = new ArcGISTiledMapServiceLayer(localStorage.getItem('Roads'), roadsObj);

let labelRoadsObj = { id: '3', title: 'Label Roads' }; let labelRoads = new ArcGISTiledMapServiceLayer(localStorage.getItem('LabelRoads'), labelRoadsObj);

let facilityObj = { id: '4', title: 'Facility Area Labels' }; let facilty = new ArcGISTiledMapServiceLayer(localStorage.getItem('Facility'), facilityObj);

let landmarksObj = { id: '5', title: 'Landmarks', slider: true }; let landmarks = new ArcGISTiledMapServiceLayer(localStorage.getItem('Landmarks'), landmarksObj);

mp.addLayers([base, roads, labelRoads, facilty, landmarks]);

this.esriMap = mp; return mp; };

Similarly for other functions related to maps

import ArcGISTiledMapServiceLayer = require('esri/layers/ArcGISTiledMapServiceLayer');

createImageryLayer() { let imagery: any; if (localStorage.getItem('Imagery') != null) { let imageryObj = { id: 'imagery', title: 'Imagery', slider: true }; imagery = new ArcGISTiledMapServiceLayer(localStorage.getItem('Imagery'), imageryObj); imagery.fullExtent = this.mapFullExtent; imagery.setMinScale(150000); this.esriMap.addLayer(imagery, 2); } } @andygup I already check that. I am using 3.x API and If I am correct the https://github.com/Esri/angular-cli-esri-map is using 4.x.

andygup commented 6 years ago

@dimpyvirk here's an working 3.23 sample of what @tomwayson was saying and based on angular-esri-cli-map. This is the pattern we recommend with Angular 5:

import {Component, OnInit, ViewChild, ElementRef, Input, Output, EventEmitter} from '@angular/core';
import { loadModules } from 'esri-loader';

@Component({
  selector: 'app-esri-map',
  templateUrl: './esri-map.component.html',
  styleUrls: ['./esri-map.component.css']
})

export class EsriMapComponent implements OnInit {

  // this is needed to be able to create the MapView at the DOM element in this component
  @ViewChild('mapViewNode') private mapViewEl: ElementRef;

  constructor() { }

  public ngOnInit() {

    // Don't forget the CSS!
    const options = {
      url: 'https://js.arcgis.com/3.23/'
    };

    loadModules([
      'esri/map'
    ], options).then(([EsriMap]) => {

      let map = new EsriMap(this.mapViewEl.nativeElement, {
        basemap: 'topo',
        center: [-122.45, 37.75],
        zoom: 13
      });

    })
    .catch(err => {
      console.error(err);
    });
  } // ngOnInit

}
tomwayson commented 6 years ago

@dimpyvirk

I have an existing code using angular 2, API 3.18 and webpack. It is working fine with import.

I'm guessing that it's either using a special configuration of webpack or a system-js library like esri-system-js, right?

esri-loader is an alternative to those, which has many benefits, but one of the drawbacks is that you cannot use import statements for 'esri' modules.

andygup commented 6 years ago

@dimpyvirk I'm going to go ahead and close this out...if you have addt'l issues please feel free to reopen.

KevinKelchen commented 6 years ago

Hi @andygup and @tomwayson !

Some contextual background: Our Ionic Angular application is also currently on API 3.x and pretty much has the special configuration that @tomwayson described in the above comment. I am working on moving the app to Ionic 4 which uses the Angular CLI instead of Ionic's custom toolchain. This move from custom config for Angular to the CLI for the 3.x API is very similar to the OP's situation. I am trying to avoid ejecting from the CLI and customizing the webpack config. Because of this, moving to esri-loader becomes even more of an appealing proposition.

Questions: In the 3.x example provided above, how do you get TypeScript's type-checking without importing types and not having the special __esri global available? The README seems to imply that you should still import types like import MapUtils from "esri/arcgis/utils";. However, I get the impression just a little from the above discussion that perhaps this is questionable and it should be done another way. Is there an example available for importing types for 3.x in an Angular CLI app (with build configuration and usage)? I only saw the one for the 4.x API.

Thanks a lot for helping those of us using modern JS frameworks integrate with the JS SDK! šŸ˜ƒ

Kevin

tomwayson commented 6 years ago

I have no idea how to use 3.x types.

Maybe https://github.com/Esri/esri-loader/issues/119 could work???

KevinKelchen commented 6 years ago

Thanks for the response and suggestion, @tomwayson . šŸ™‚

I've attempted using the TS type importing referred to in #119 but was still getting build errors about not being able to resolve the esri modules being referenced. I may very well have had something not configured correctly, however. Since the technique may not yet be proven for use with the esri JS SDK, I was thinking the path of least resistance to get types in 3.x working was to do it the way it's currently recommended and known to work today. @andygup , is there a more complete example available for 3.x with the Angular CLI that has types working? It would be greatly valued if there was. šŸ˜€

Thank you so much!

Kevin

tomwayson commented 6 years ago

Thanks for trying.

As far as I know, a 3.x types esri-loader example is like Sasquatch, many people claim to have seen it, but there is no concrete evidence of it's existence.

andygup commented 6 years ago

@KevinKelchen I dug around and couldn't find any 3.x types example(s) either. ...like Sasquatch šŸ˜„

For your question about the code pattern snippet above that snippet is for 4.x and doesn't use any types or type checking. I know you aren't using 4.x, but here's an old 4.x types example + Angular: https://github.com/Esri/angular-cli-esri-map/commit/e4a64b3c9b821a5234f344c04f193db1f300c712#diff-2b32220f520753a373615d05469e578dR16

Also note, AFAIK Angular 6 doesn't officially support webpack eject, so esri-loader is still the preferred approach for Angular 6. CLI 7 just released a week ago and I haven't had a chance to verify it. Reference: https://github.com/angular/angular-cli/issues/10618

KevinKelchen commented 6 years ago

Thank you, @tomwayson and @andygup !

@andygup, I appreciate you taking the time to search for examples! šŸ˜ƒ I, too, learned that the CLI doesn't support ejecting ATM. However, I did see some workaround and "hacky" solutions that allow customizing the webpack config without ejecting...

To be clear about the Sasquatch specifics (šŸ˜›), is it specifically 3.x types with the Angular CLI that don't exist? If so, what about Angular apps that don't use the CLI? Also, is the Sasquatch referring specifically to the use of esri-loader with 3.x types as opposed to other solutions (such as loading everything with dojo and customizing the webpack config)? The README seems to imply you can get types for 3.x, so I just want to make sure I understand. šŸ™‚

Thank you!

Kevin

andygup commented 6 years ago

is it specifically 3.x types with the Angular CLI that don't exist?

You can definitely use the ArcGIS JS API 3.x types with Angular 2+. It's just that there aren't any samples demonstrating the use of those types with esri-loader.

If so, what about Angular apps that don't use the CLI?

Same comment. The Angular component structure is the same whether you manually create components or use the CLI. CLI is just significantly faster than creating components by hand.

tomwayson commented 6 years ago

is the Sasquatch referring specifically to the use of esri-loader with 3.x types as opposed to other solutions (such as loading everything with dojo and customizing the webpack config)?

That is exactly what I meant. Regardless of Angular, I'm not aware of any examples of esri-loader w/ the 3.x types (in React, or whateves).

There were many conversations that lead me to believe that it was theoretically possible, maybe even others claiming they'd done it. That's why I left that cagily worded bit in the README about 3.x b/c I didn't want to discourage people if it was possible. I guess, like Sasquatch, I just really wanted to believe.

At this point I think we should update README to say this probably won't work w/ 3.x types,

tomwayson commented 6 years ago

Now, I'm going to put my :trollface: hat on - aren't types optional?

KevinKelchen commented 6 years ago

Thanks again, @andygup and @tomwayson ! That all makes sense. Thanks for your prompt replies and for taking the time to help me!

I agree it's not a functional requirement to have type-checking for the JS SDK; it will definitely still work at runtime. As an Ionic/Angular/TypeScript user I really value having the types available for compile-time safety and intellisense. I recognize that the degree to which I value something may differ from that of others. šŸ™‚

I will give esri-loader serious consideration during this migration to Ionic 4 and the Angular CLI. I may still try to experiment with getting types to work, but given the recommendation from you for Angular CLI apps and my desire to avoid ejecting from the CLI, I may end up biting the bullet and going type-less if I have to.

Thanks again!

Kevin

andygup commented 6 years ago

Also, the 3.x types don't export the interfaces that you would typically expect, it's things like esri.BasemapOptions and such.

andygup commented 6 years ago

@KevinKelchen and for anyone else looking to use esri types with Angular, here are some example usage snippets: https://github.com/Esri/angular-cli-esri-map/issues/17

tomwayson commented 6 years ago

I always suspected @andygup was a Sasquatch hunter! That issue is like the Patterson Film for esri-loader.

KevinKelchen commented 6 years ago

Thank you for those examples, @andygup ! I will give it a shot! šŸ˜ƒ

duavipul commented 5 years ago

@KevinKelchen @andygup @tomwayson I want to render our Mapping Application from MapViewer of our Portal for ArcGIS using Angular 7 Project.How I can do that.Please let me know.

tomwayson commented 5 years ago

@duavipul

It sounds like you want to embed the map (or application) in your Angular application using an iframe.

andygup commented 5 years ago

šŸ‘† this is a duplicate issue from here. I've sent Vipul an email.

duavipul commented 5 years ago

Hello Tom,

I don't want to use Iframe as it is not good practice, rest you can tell me how we can do that.I have webbuilder package which I can get it embedded in my Angular application, or I can embed esri map via portal id. But every time the hit goes from arcgis, I am not able to get our mapviewer application or map.Is there any way I can show the map viewer appkication with widgits & layers in it in my Angular application.

Thanks & regards Vipul Dua

On Wed, Dec 19, 2018, 9:04 PM Tom Wayson <notifications@github.com wrote:

@duavipul https://github.com/duavipul

It sounds like you want to embed the map (or application) https://doc.arcgis.com/en/arcgis-online/share-maps/embed-maps-groups.htm in your Angular application using an iframe.

ā€” You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/Esri/esri-loader/issues/95#issuecomment-448637514, or mute the thread https://github.com/notifications/unsubscribe-auth/AFV4-_V0XXkK4u_TcWO1ALyXBsrqYozTks5u6lyGgaJpZM4SRKRO .