ghettovoice / vuelayers

Web map Vue components with the power of OpenLayers
https://vuelayers.github.io/
MIT License
680 stars 227 forks source link

AssertionError: component has "$map" property #344

Closed TitanFighter closed 4 years ago

TitanFighter commented 4 years ago

According to the issue [Vuelayers map not showing in tab vue](this.$refs.map.updateSize()) I need to execute this.$refs.map.refresh() but it throws AssertionError: component has "$map" property.

Here is the code:

<template>
  <vl-map
    ref="map"
    :load-tiles-while-animating="true"
    :load-tiles-while-interacting="true"
    data-projection="EPSG:4326"
    style="height: 400px"
  >
    <vl-view :zoom.sync="mapSettings.zoom" :center.sync="mapSettings.center" :rotation.sync="mapSettings.rotation" />

    <vl-layer-tile>
      <vl-source-osm />
    </vl-layer-tile>

    <vl-layer-vector>
      <vl-source-vector ident="marker-target" :features.sync="markers" />

      <vl-style-box>
        <vl-style-icon :src="require('./assets/marker.png')" :scale="0.4" :anchor="[0.5, 0.8]" />
      </vl-style-box>
    </vl-layer-vector>

    <vl-interaction-draw
      :active="markers.length < 1"
      source="marker-target"
      type="point"
    />
    <vl-interaction-modify
      source="marker-target"
    />
    <vl-interaction-snap source="marker-target" :priority="10" />
  </vl-map>
</template>

<script>
export default {
  name: 'map',

  data () {
    return {
      mapSettings: {
        zoom: 1,
        center: [0, 33.752],
        rotation: 0
      },
      markers: []
    }
  },

  mounted () {
    this.$refs.map.refresh()
  }
}
</script>

Trace:

AssertionError: component has "$map" property
    at assert (webpack-internal:///./node_modules/vuelayers/lib/util/assert.js:83:11)
    at hasMap (webpack-internal:///./node_modules/vuelayers/lib/util/assert.js:124:3)
    at VueComponent.updateSize (webpack-internal:///./node_modules/vuelayers/lib/map/index.js:362:67)
    at VueComponent.refresh (webpack-internal:///./node_modules/vuelayers/lib/map/index.js:334:12)
    at VueComponent.mounted (webpack-internal:///./node_modules/cache-loader/dist/cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/components/pages/Profiles/TheProfileOpenLayersMap.vue?vue&type=script&lang=js&:29:20)
    at invokeWithErrorHandling (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:1853:57)
    at callHook (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:4213:7)
    at Object.insert (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:3136:7)
    at invokeInsertHook (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:6336:28)
    at VueComponent.patch [as __patch__] (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:6555:5)

What do I do wrong?

ghettovoice commented 4 years ago

Hello @TitanFighter , this is true, in the mounted hook internal ol.Map instance can be not yet initialized.

So you should use:

  1. create promise this.$refs.map.$createPromise.then(() => this.$refs.map.refresh()) or
  2. run refresh in the created or mounted event hook.
<vl-map
    ref="map"
    :load-tiles-while-animating="true"
    :load-tiles-while-interacting="true"
    data-projection="EPSG:4326"
    style="height: 400px"
    @created="vm => vm.refresh()"
  >
...
</vl-map>