tomwayson / esri-angular-cli-example

Example of how to to use the ArcGIS API for JavaScript in an Angular CLI app

Home Page:https://tomwayson.github.io/esri-angular-cli-example

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Calling map service RESTful url

ashrafonline opened this issue · comments

The title says it all , I don't want to consume a portal map , I've my own map service and I want to display it .
Thanks

You can do that.

The esri4-map component has a mapProperties attribute, which I assume corresponds to the
properties you can pass to new Map() which includes basemap and layers. If that doesn't work for you, that also has a mapInit event which gives you access to the map and map view that you can modify (add layers, etc) as needed:

  onMapInit(mapInfo: {map: __esri.Map, mapView: __esri.MapView}) {
    // add a layer to the map here
  }

Alternatively you can create your own map component that uses angular2-esri-loader to require whatever modules you need to create the map and add the layer.

Thank you , @tomwayson
The first approach didn't work with me , as the namespace __esri is not accessible inside onMpaInit .
But angular2-esro-loader did the trick for me .
Also I managed to modify the code to access the latest ArcGIS JS API which is 4.3

url: '//js.arcgis.com/4.3/'

this.esriLoader.loadModules(['esri/Map', 'esri/views/MapView', 'esri/layers/MapImageLayer', 'dojo/domReady!'])

this.map = new Map({basemap: 'topo'});
this.mapView = new MapView({map: this.map, container: "xyz"});
this.layer = new MapImageLayer({url:"https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer"});

this.map.add(this.layer)

Thanks a lot .

Glad you got it working.

FYI - You should not use dojo/domReady!

namespace __esri is not accessible inside onMpaInit

You would need to install the types in your app first. Or just use any that's what I do b/c TypeScript hates me.

I managed to modify the code to access the latest ArcGIS JS API which is 4.3

You should not need to modify any code to do that. You can pass the url to the version to .load()

this.esriLoader.load({
      // use a specific version of the API
      url: 'https://js.arcgis.com/4.3'
    });

You should not need to modify any code to do that. You can pass the url to the version to .load()

ESRI changed the modules names since 4.x , for instance 'esri/map' became 'esri/Map' . Also they introduced some new modules like MapView, MapImageLayer etc ..

FYI - You should not use dojo/domReady!

Correct .

Yes, we also released updated the types, which you should be able to install and use following these instructions: https://github.com/tomwayson/angular2-esri-loader#arcgis-types

I'd be interested to know if that works for you. The last time I tried that in an angular-cli app it I could use the types in VS Code, but ng-serve showed a (fatal! what amazing DX) error: ERROR in /path/to/my/app/src/app/esri-map/esri-map.component.ts (14,19): Cannot find namespace '__esri'.

Everyone loves TypesScript, but it hates me, which is why I use any.

I tried it , with no luck . I keep getting an error in import modules , later on I saw a comment somewhere that I could add a property in the compiler config file , tried it also and the error still there .

I think for now the loader you wrote is the best solution . I'll try to publish an example using it with some of 4.3 capabilities .

BTW TypeScript hates me as well . You are not alone :)

Thanks Man.

Ha! I thought I was the only one.

So are you using angular-cli as well?

So are you using angular-cli as well?

Yep , I published my code here

@ashrafonline, thanks for publishing your example. I took what you did and got it working inside the structure of this repo using the angular2-esri4-components library. Take a look at my example here.

If you continue to have issues with the TypeScript annotations I could take a look at it for you and see if I can help. Please just publish an example that has the TS issues and let me know.

@kgs916 thanks for your comment . Would you please modify your example to see how could you call a map service instead of portal itemid . That was the issue that I couldnt do.

@kgs916

When I noticed the above build errors when using the 4.x types was when I was walking through the steps to add the new add JSAPI to your own angular-cli app instructions to the README. If you follow the steps in my gist but try to use the __esri namespace types instead of any in the component I'd expect you'd see the same build errors.

I would love to have your eyes on those instructions, or even better have you try to walk through them, to see if there's anything I missed that would enable that to work. I know you got the 4.x types working in your library, and this app uses that library and the 4.x types and I don't see those build errors here, so I'm a bit 😕 .

@kgs916

I went through your example , It worked with me , I recognized that I should load ESRI modules via this.esriLoader.loadModules .
I think this was the point I was missing , Though I still believe that I could logically get them loaded automatically when I call something like tileLayer: __esri.TileLayerConstructor , correct me if I'm wrong .

@tomwayson

There is one addition to your steps that is necessary in order to start being able to use the arcgis-js-api types in your code. You must include it in the types array in the tsconfig.app.json file. It should look something like this:

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "outDir": "../out-tsc/app",
    "module": "es2015",
    "baseUrl": "",
    "types": [
      "arcgis-js-api"
    ]
  },
  "exclude": [
    "test.ts",
    "**/*.spec.ts"
  ]
}

You will also need to add it to the tsconfig.spec.json file:

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "outDir": "../out-tsc/spec",
    "module": "commonjs",
    "target": "es5",
    "baseUrl": "",
    "types": [
      "jasmine",
      "node",
      "arcgis-js-api"
    ]
  },
  "files": [
    "test.ts"
  ],
  "include": [
    "**/*.spec.ts",
    "**/*.d.ts"
  ]
}

The tsconfig.json file that is in the root of the project does "typeRoots": ["node_modules/@types"] to include everything from @types but in the app and spec files they want you to be much more explicit.

Once you have done this then your esri-map.component.ts file can be updated to:

import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';

// also import the "angular2-esri-loader" to be able to load JSAPI modules
import { EsriLoaderService } from 'angular2-esri-loader';

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

  // for JSAPI 4.x you can use the "any for TS types
  public mapView: __esri.MapView;

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

  constructor(
    private esriLoader: EsriLoaderService
  ) { }

  public ngOnInit() {
    // only load the ArcGIS API for JavaScript when this component is loaded
    return this.esriLoader.load({
      // use a specific version of the JSAPI
      url: '//js.arcgis.com/4.3/'
    }).then(() => {
      // load the needed Map and MapView modules from the JSAPI
      this.esriLoader.loadModules([
        'esri/Map',
        'esri/views/MapView'
      ]).then(([
        Map,
        MapView
      ]: [ __esri.MapConstructor, __esri.MapViewConstructor]) => {
        const mapProperties: __esri.MapProperties = {
          basemap: 'hybrid'
        };

        const map = new Map(mapProperties);

        const mapViewProperties: __esri.MapViewProperties = {
          // create the map view at the DOM element in this component
          container: this.mapViewEl.nativeElement,
          // supply additional options
          center: [-12.287, -37.114],
          zoom: 12,
          map // property shorthand for object literal
        };

        this.mapView = new MapView(mapViewProperties);
      });
    });
  }

}

@ashrafonline

Simply calling tileLayer: __esri.TileLayerConstructor is not enough. This will simply type a variable as TileLayerConstructor in your code editor. When the TypeScript is transpiled to JavaScript it will not become an instance of TileLayer. It is important that you do something like this to load in the TileLayer module:

        this.esriLoader.loadModules([
          'esri/layers/TileLayer'
        ]).then(([
          TileLayer
        ]: [__esri.TileLayerConstructor]) => {
          const tileLayer = new TileLayer();
          /* ... other code */
        });

@kgs916

I thought the same concept of __esri.Map and __esri.MapView could be applied on __esri.MapImageLayerConstructor as you could use them directly without the need of importing 'esri/layers/Map' and 'esri/layers/MapView.

I would be much happier If I could use them(and other modules) directly without the importing part .

@ashrafonline

I think I see what you are saying. When passing the layers property to the MapConstructor, it looks like supports casting an array of layer instances to a collection, but it may not support casting an array of POJOs (i.e. the constructor properties for each layer). Is that the issue?

@tomwayson

I wanted to say : calling __esri.SomethingConstructor should automatically load the module esri/Something , exactly as same as __esri.Map and __esri.MapView .

calling __esri.SomethingConstructor should automatically load the module esri/Something , exactly as same as __esri.Map and __esri.MapView

I'm not sure what you mean. Calling new Map() does not automatically load the esri/Map module.

@tomwayson
Never mind ,I got what I was looking for , my concern was in saving some sort of codes , no more or less.