Map Not Displaying on Vue 2 with TypeScript and ES Modules

1723
6
Jump to solution
08-04-2022 09:01 AM
MollyWhitener
Emerging Contributor

I cannot get my map to display in my Vue 2 web app. I've done my best to follow the typing guide for ES Modules as well as the set up for TypeScript. I've tried some suggestions others have done, and those don't work either. The app compiles and runs and shows no errors. But the map does not display at all. 

Does anyone have any idea what I'm doing wrong?

 

 

//tsconfig.json
{
  "compilerOptions": {
    "strict": true,
    "jsx": "preserve",
    "importHelpers": true,
    "moduleResolution": "node",
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "sourceMap": true,
    "module": "ES2020",
    //"moduleResolution": "Node",
    "resolveJsonModule": true,
    "target": "ES2020",
    "baseUrl": ".",
    "types": [
      "webpack-env"
    ],
    "paths": {
      "@/*": [
        "src/*"
      ]
    },
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost",
      "ES2020",
      "DOM"
    ]
  },
  "include": [
    "./src",
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "tests/**/*.ts",
    "tests/**/*.tsx"
  ],
  "exclude": [
    "node_modules"
  ]
}
//main.ts

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import vuetify from './plugins/vuetify'
import { ADLogin } from "@wwinc/NPM-VueADRedirect";
import { SecurityService } from './services/security-service';
import 'leaflet/dist/leaflet.css';
import { Icon } from 'leaflet';
import esriConfig from '@arcgis/core/config';

//esriConfig.assetsPath = 'https://js.arcgis.com/4.24/@arcgis/core/assets';
//esriConfig.assetsPath = './src/assets';
esriConfig.assetsPath = '../node_modules/@arcgis/core/assets';
esriConfig.apiKey = "APIKEY";

type D = Icon.Default & {
  _getIconUrl?: string;
};

delete (Icon.Default.prototype as D)._getIconUrl;
Icon.Default.mergeOptions({
  iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png'),
  iconUrl: require('leaflet/dist/images/marker-icon.png'),
})

Vue.config.productionTip = false

console.log(`
Environment Settings:  
  logonPageURL: ${process.env.VUE_APP_LOGINSITE_URL},
  logonApiURL: ${process.env.VUE_APP_LOGONAPI_URL},
  redirectURL: ${process.env.VUE_APP_LOGINREDIRECT_URI},
  baseURL: ${process.env.VUE_APP_BASE_URL},
  apiURL: ${process.env.VUE_APP_REP_API},
`)

Vue.use(ADLogin, {
  router,
  logonPageURL: process.env.VUE_APP_LOGINSITE_URL,
  logonApiURL: process.env.VUE_APP_LOGONAPI_URL,
  redirectURL: process.env.VUE_APP_LOGINREDIRECT_URI,
  store,
  debug: false
});

new Vue({
  router,
  store,
  vuetify,
  render: h => h(App)
}).$mount('#app')

Vue.$security = new SecurityService();
Vue.prototype.$security = Vue.$security;
//main.css
@import "https://js.arcgis.com/4.24/@arcgis/core/assets/esri/themes/light/main.css";html,
body,
#app {
    font-family: Avenir, Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
    padding: 0;
    margin: 0;
    width: 100%;
    height: 100%;
}
.mapdiv {
    padding: 0;
    margin: 0;
    height: 80vh;
}
//vue.config.js

let CopyPlugin;
CopyPlugin = require('copy-webpack-plugin');

module.exports = {
  publicPath: '/RepWrangler/',
  configureWebpack: {
    plugins: [
      new CopyPlugin([
        { from: 'web.config', to: './' },
      ]),
    ],
    devtool: 'source-map'
  },
  transpileDependencies: [
    'vuetify', '@arcgis/core'
  ],
  devServer: {
    disableHostCheck: true
  }
}

 

 

 

//App.vue

<template>
  <v-app id="app">
    <v-app-bar
      app
      color="primary"
      absolute
    >
        <v-img
          class="shrink ma-2"
          contain
          :src="require('../src/assets/cowboy.png')"
          transition="scale-transition"
          max-height="40"
          max-width="40"
        />

      <v-toolbar-title>
        Rep Wrangler
      </v-toolbar-title>

      <v-spacer></v-spacer>

      <v-tooltip bottom>
        <template v-slot:activator="{on}">
          <v-btn icon v-on="on" @click="logout">
            <v-icon>mdi-logout</v-icon>
          </v-btn>
        </template>
        <span>Logout</span>
      </v-tooltip>


      <template v-slot:extension>
        <v-tabs align-with-title>
          <router-link
            style="display: flex"
            to="/">
            <v-tab style="color: white">Home</v-tab>
          </router-link>
          <router-link
            style="display: flex"
            to="/map">
            <v-tab style="color: white">Retailers</v-tab>
          </router-link>
          <router-link
            style="display: flex"
            to="/reptable">
            <v-tab style="color: white">Reps</v-tab>
          </router-link>
          <router-link
              style="display: flex"
              to="/zipsearch">
            <v-tab style="color: white">Zip Search</v-tab>
          </router-link>
        </v-tabs>
      </template>

    </v-app-bar>

    <v-main>
      <router-view/>
    </v-main>
  </v-app>
</template>

<script lang="ts">
import Vue from 'vue';

export default Vue.extend({
  name: 'App',

  methods: {
    logout() {
      this.$logout();
    }
  },

  async beforeMount() {
    await this.$store.dispatch('JWT');
  }
});
</script>

<style>
#app{
  background-color: var(--v-background-base) !important;
}

</style>
//MapComponent.vue

<template>
  <div class="mapdiv"></div>
</template>

<script lang="ts">
import Vue from 'vue';
import Map from '@arcgis/core/Map';
import MapView from '@arcgis/core/views/MapView';
import FeatureLayer from '@arcgis/core/layers/FeatureLayer';
import esriConfig from "@arcgis/core/config";


export default Vue.extend({
    name: "RepZipMap",

    async mounted() {
        esriConfig.apiKey = "APIKEY";
        esriConfig.assetsPath = 'https://js.arcgis.com/4.24/@arcgis/core/assets';

        const apiKey = "APIKEY";

        const map = new Map({
          basemap: "arcgis-streets" // Basemap layer service
        });

        const view = new MapView({
          map: map,
          center: [-92.0932, 38.232], // Longitude, latitude
          zoom: 5, // Zoom level
          container: 'mapdiv' // Div element
        });

        const zipLabelClass = {
          labelExpressionInfo: {
            expression: "$feature.ZIP_CODE"
          },
          labelPlacement: "above-center",
        }

        const featureLayer = new FeatureLayer({
          apiKey: "APIKEY",
          url: "https://services.arcgis.com/P3ePLMYs2RVChkJx/arcgis/rest/services/USA_Boundaries_2021/FeatureServer/3",
          opacity: 0.4,
        });

        featureLayer.labelingInfo = [ zipLabelClass ];
        map.add(featureLayer);
    }
})
</script>

<style scoped>
   @import '../main.css';
</style>

 

 

0 Kudos
1 Solution

Accepted Solutions
ReneRubalcava
Esri Frequent Contributor

Make these changes in your vue file. Your MapView was referencing the div className, and it had no id.

 

<div id="viewDiv" class="mapdiv"></div>

const view = new MapView({
    map: map,
    container: "viewDiv",
    center: [-118.244, 34.052],
    zoom: 12
});

 

  You might also need to change the browserlist in the package.json. This is what we support.

  "browserslist": [
    "last 1 Chrome version",
    "last 1 Firefox version",
    "last 2 Edge major versions",
    "last 2 Safari major versions",
    "last 2 iOS major versions",
    "Firefox ESR"
  ]

 

Plus, I don't the assets are copied correctly in a production build, they should be in the public folder to get copied in a build, but if you don't use local assets, you don't need to worry about it.

View solution in original post

0 Kudos
6 Replies
ReneRubalcava
Esri Frequent Contributor

Can you break this down to simpler reproducible sample without routing, auth and environment variables in a github repo? Can't tell from what you've posted.

Only Vue2 app I have is this one, but it's a few years old and not sure it works anymore. It could be something in the dependencies or some other unknown.

https://github.com/odoe/jsapi-vue-template

0 Kudos
MollyWhitener
Emerging Contributor

Okay, I tried doing a very simple version as well, and it doesn't work here either.
https://github.com/mollyjw/ARCGis-Vue2

I guess I will just try to do Esri Leaflet instead of the JS API.

0 Kudos
ReneRubalcava
Esri Frequent Contributor

Do you need to have the assets copied locally? Looks like something in the build is causing an issue there. You can remove the config.assetsPath part and load the assets from the CDN. Everything seems to work after that.

0 Kudos
MollyWhitener
Emerging Contributor

I tried it without copying the assets, and I just got a blank page. Are you seeing something?

0 Kudos
ReneRubalcava
Esri Frequent Contributor

Make these changes in your vue file. Your MapView was referencing the div className, and it had no id.

 

<div id="viewDiv" class="mapdiv"></div>

const view = new MapView({
    map: map,
    container: "viewDiv",
    center: [-118.244, 34.052],
    zoom: 12
});

 

  You might also need to change the browserlist in the package.json. This is what we support.

  "browserslist": [
    "last 1 Chrome version",
    "last 1 Firefox version",
    "last 2 Edge major versions",
    "last 2 Safari major versions",
    "last 2 iOS major versions",
    "Firefox ESR"
  ]

 

Plus, I don't the assets are copied correctly in a production build, they should be in the public folder to get copied in a build, but if you don't use local assets, you don't need to worry about it.

0 Kudos
MollyWhitener
Emerging Contributor

OH MY GOSH YOU'RE A GENIUS!

 

I didn't realize it had to be an id; I thought it was a class. 

 

Thank you thank you so much!

0 Kudos