D
D
dicem2020-02-10 18:37:28
Yandex maps
dicem, 2020-02-10 18:37:28

How to properly initialize Yandex Maps API in Vue?

Please tell me, I’m sawing the project, it so happened that the previous developers connected the cards through a script in the global scope, and now I have to integrate everything into Vue, I make the delivery field in the online store, I connect the trace to the project. way:

data() {
    return {
        dropdownIsOpened: false,
        SuggestView: null,
        bounds: {
            100000003:[ // Москва
                [55.142627, 36.803259],
                [56.021281, 37.967682]
            ],
            100000006:[ // Самара
                [53.091785, 49.731327],
                [53.550907, 50.390439]
            ],
            100000008:[ // Сочи
                [43.384759, 39.149676],
                [44.029925, 40.010388]
            ]
        },
        provider: {
            suggest: function (request, options) {
                delete options['provider'];
                return ymaps.suggest(request, options).then(items => {
                    let arrayResult = [];
                    let arrayPromises = [];

                    function pushGeoData(displayName, value, jsonData) {
                        arrayResult.push({displayName: displayName, value: value, jsonData: jsonData});
                    }

                    items.forEach(i => {
                        arrayPromises.push(ymaps.geocode(i.value).then(gc => {
                            let displayName = "";
                            let value = i.value;
                            if (!i.value.match(/.*подъезд.*/)) {
                                let geoObject = gc.geoObjects.get(0);

                                if (geoObject) {
                                    let jsonData = JSON.stringify({
                                        'city': geoObject.getLocalities()[0] || geoObject.getAdministrativeAreas()[0],
                                        'street': geoObject.getThoroughfare() || geoObject.getLocalities()[0],
                                        'house': geoObject.getPremiseNumber(),
                                    });

                                    if (geoObject.getCountryCode() == "RU") {
                                        value = value.replace(geoObject.getCountry()+", ", "");
                                        value = value.replace(geoObject.getAdministrativeAreas()[0]+", ", "");
                                        displayName = "<div class='yandex-map-address_info'>"+value+"</div><div class='yandex-map-localities_info'>"+geoObject.getCountry()+", "+geoObject.getLocalities()[0]+"</div>";
                                        value = value.replace("undefined", "");
                                        displayName = displayName.replace("undefined", "");

                                        pushGeoData(displayName, value, jsonData);
                                    }
                                }
                            }
                        }));
                    })

                    return Promise.all(arrayPromises).then(function(){
                        console.log(arrayResult)
                        return ymaps.vow.resolve(arrayResult);
                    });
                })
            }
        }
    };
},
computed() {
  ...
  geoInput() {
    return document.getElementById('geo-select__input').querySelector('.app-select__input')
  },
},
methods: {
  yaMapInit() { // methods()
  this.SuggestView = new ymaps.SuggestView(this.geoInput, {
    provider: this.provider,
    boundedBy: this.bounds[this.brandCode]
  });
},
mounted() {
  ymaps.ready(this.yaMapInit());
}


I get TypeError: "ymaps.SuggestView is not a constructor". I don’t understand at all why, I tried wrapping initialization in DOMContentLoaded and got something like yaCounter..... is not defined well, nothing actually happened. I understand that connecting maps outside the context of Vue is not a good idea, but I don’t even know what to do anymore.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Alex, 2020-02-10
@dicem

Try connecting the Yandex script at the time of component initialization. And the yaMapInit method should be launched after this script is loaded.
Additionally, it is worth considering deleting the script when deleting the component.
Example:

created() { // или даже beforeCreated()
  const script = document.createElement('script')
  
  script.onload = () => {
    ymaps.ready(() => this.yaMapInit());
    // или
    // this.yaMapInit()
  };
  
  script.id = 'ymaps'
  script.src = "https://api-maps.yandex.ru/2.1/?apikey=ваш API-ключ&lang=ru_RU"
  document.head.append(script);
},

destroyed() {
  document.head.querySelector('script#ymaps').remove()
  // ymaps = null
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question