No More Posting New Topics!

If you have a question or an issue, please start a thread in our Github Discussions Forum.
This forum is closed for new threads/ topics.

Navigation

    Quasar Framework

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search

    Google Maps from CDN problem

    Help
    3
    19
    3410
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • A
      atelier last edited by

      @a47ae Thanks for your reply. I’m familiar with the Vue Google Maps components, but I don’t think that approach will work for my use case as I’m needing to integrate custom map code from Algolia.

      As @benoitranque suggested, I created an externalApi.js file which includes the code from his post. I then created a new plugin called ‘google’ and registered it with Quasar. This plugin uses the import command as referenced in the ‘main.js’ section of his post. This causes the dependency error. Quasar can’t find externalApi. Being relatively new to Quasar/Vue, I’m probably just overlooking something.

      This is frustrating because I can include the script in the index.html file of a stock Vue installation and it works fine. It would be helpful if Quasar behaved in a similar way.

      1 Reply Last reply Reply Quote 0
      • benoitranque
        benoitranque last edited by

        let me write up a newer version or this, self contained, for use in 0.15

        1 Reply Last reply Reply Quote 0
        • a47ae
          a47ae last edited by

          @atelier Sure you can’t use this? You can pass whatever Google Maps option you need as a prop named options to <GoogleMapsMap> So you could fetch the options from algolia and jsut pass them. 🙂

          See this line in the src: https://github.com/Akryum/vue-googlemaps/blob/master/src/components/Map.vue#L126

          @benoitranque Nice! During my eesarch for solutions I found react-load-script
          Maybee you could create something similar for Vue.js or even as QLoadScript component? 😃
          Should be relative straightforward for your current code.

          1 Reply Last reply Reply Quote 0
          • benoitranque
            benoitranque last edited by

            @a47ae yeah the idea was an async loadscript util. So if you have a large app and say use google maps in only one page, you only want to load google api when that page is visited.
            @atelier here is a v0.15 plugin

            // import something here
            
            // leave the export, even if you don't use it
            export default ({ app, router, Vue }) => {
              // something to do
              let 
                id = 'google-cdn' // must be unique
                url = 'https://maps.googleapis.com/maps/api/js?key=xxxxxxxxxxxxxxxxxxx'
            
            
              /*
               Usage in component
                
                async mounted () {
                  await this.$google
                  // google now loaded
                }
                
               Alternative 
            
                methods {
                  async initGmaps () {
                    await this.$google
                    // google now loaded
                  }
                }
               */
            
              this.$google = new Promise((resolve, reject) => {
                if (document.getElementById(id)) {
                  console.error(`Error loading ${url} async: ${id} is not unique`)
                  return
                }
                let script = document.createElement('script')
                script.src = url
                script.async = true
                script.id = id
                script.onload = () => {
                  resolve()
                }
                script.onerror = (err) => {
                  reject(err)
                }
                document.body.appendChild(script)
              })
            }
            
            1 Reply Last reply Reply Quote 1
            • A
              atelier last edited by

              @benoitranque This is still not working. I added your code to a new plugin and registered it with Quasar, however I’m getting undefined errors for ‘google’ and ‘map’ when loading the page with the Algolia code.

              I don’t know if this will be of any help, but here is the code I’m trying to implement:

              https://www.algolia.com/doc/tutorials/geo-search/displaying-results-in-google-map/

              I really appreciate your efforts in helping to resolve this.

              1 Reply Last reply Reply Quote 0
              • benoitranque
                benoitranque last edited by benoitranque

                After implementation of my code, use this is any component:

                    async mounted () {
                      await this.$google
                      // google now loaded
                      console.log(google)
                    }
                

                edit: please confirm whether google is loading properly using this

                then use the native google maps implementation

                1 Reply Last reply Reply Quote 0
                • A
                  atelier last edited by

                  I tried it in a couple different components and I’m getting a ‘google’ is not defined error.

                  1 Reply Last reply Reply Quote 0
                  • benoitranque
                    benoitranque last edited by benoitranque

                    Couple errors on my side, apologies. This should work

                    // import something here
                    var promise = null
                    // leave the export, even if you don't use it
                    export default ({ app, router, Vue }) => {
                      // something to do
                      let 
                        id = 'google-cdn' // must be unique
                        url = 'https://maps.googleapis.com/maps/api/js?key=xxxxxxxxxxxxxxxxxxx'
                    
                    
                      /*
                       Usage in component
                        
                        async mounted () {
                          await this.$google()
                          // google now loaded
                        }
                        
                       Alternative 
                    
                        methods {
                          async initGmaps () {
                            await this.$google()
                            // google now loaded
                          }
                        }
                       */
                    
                      Vue.prototype.$google = function () {
                        if (!promise) {
                          promise = new Promise((resolve, reject) => {
                            if (document.getElementById(id)) {
                              console.error(`Error loading ${url} async: ${id} is not unique`)
                              return
                            }
                            let script = document.createElement('script')
                            script.src = url
                            script.async = true
                            script.id = id
                            script.onload = () => {
                              resolve()
                            }
                            script.onerror = (err) => {
                              reject(err)
                            }
                            document.body.appendChild(script)
                          })
                        }
                        return promise
                      }
                    }
                    

                    edited…

                    1 Reply Last reply Reply Quote 0
                    • A
                      atelier last edited by

                      No luck. I’m still getting ‘google’ not defined error. FYI, I did have to add ‘let =’ before url to define that variable. Not sure if that is affecting your logic.

                      1 Reply Last reply Reply Quote 0
                      • A
                        atelier last edited by

                        Am I supposed to change ‘google-cdn’ with some other value?

                        1 Reply Last reply Reply Quote 0
                        • a47ae
                          a47ae last edited by

                          I just checked from a brand new Quasar project and @benoitranque solution works fine.
                          You first have to create a file src/plugins/maps.js (or run quasar new plugin maps) and add the following:

                          let promise = null
                          
                          export default ({ app, router, Vue }) => {
                            let
                              id = 'google-cdn',
                              url = 'https://maps.googleapis.com/maps/api/js?key=<add-your-key-here>'
                          
                            Vue.prototype.$google = function () {
                              if (!promise) {
                                promise = new Promise((resolve, reject) => {
                                  if (document.getElementById(id)) {
                                    console.error(`Error loading ${url} async: ${id} is not unique`)
                                    return
                                  }
                                  let script = document.createElement('script')
                                  script.src = url
                                  script.async = true
                                  script.id = id
                                  script.onload = () => {
                                    resolve()
                                  }
                                  script.onerror = (err) => {
                                    reject(err)
                                  }
                                  document.body.appendChild(script)
                                })
                              }
                              return promise
                            }
                          }
                          
                          

                          Then add 'maps' to the plugins array in quasar.conf.js

                          After that edit the src/pages/index.vue and add the following:

                          <template>
                            <q-page class="flex flex-center">
                              <div id="map"></div>
                            </q-page>
                          </template>
                          
                          <style>
                          #map {
                            height: 400px;
                            width: 90%;
                          }
                          </style>
                          
                          <script>
                          export default {
                            name: 'PageIndex',
                          
                            data () {
                              return {
                                map: null
                              }
                            },
                          
                            methods: {
                              initMap () {
                                this.map = new window.google.maps.Map(document.getElementById('map'), {
                                  center: {lat: -34.397, lng: 150.644},
                                  zoom: 8
                                })
                              }
                            },
                          
                            async mounted () {
                              await this.$google()
                              this.initMap()
                            }
                          }
                          </script>
                          
                          

                          Now if you run quasar run dev the browser should open and after a while you should see a map.

                          If this does not work for you I can also send you the source files.
                          From there it should be easy to adapt the Algolia tutorial. 🙂

                          1 Reply Last reply Reply Quote 2
                          • A
                            atelier last edited by

                            @a47ae I was able to display a map with the code you provided, but I’m unable to get the Algolia code to work without errors. I’m sure the problem is tied to my limited coding skills. I’ll see if I can figure it out otherwise I may have to resort to a stock Vue approach. Thanks so much to you and @benoitranque for all your help. I really appreciate the effort. I don’t want to waste any more of your time on this.

                            1 Reply Last reply Reply Quote 0
                            • a47ae
                              a47ae last edited by

                              Yeah the Algolia stuff is a bit tricky because the tutorial is intended for plain websites and not Vue.js applications.

                              You may wan to take a look at https://community.algolia.com/vue-instantsearch/ which is the official instantsearch plugin for Vue.js

                              To be honest I don’t think that it is easier in plain Vue.js, because Quasar is not really different than a plain Vue.js app.

                              If you have concrete questions do not hesitate to ask them, we are always glad to help. 🙂

                              1 Reply Last reply Reply Quote 0
                              • A
                                atelier last edited by

                                The frustrating thing is that the Algolia code works fine on a stock Vue installation after adding the Google API script to the index.html file. It also works great in a Nuxt installation. In fact, Nuxt has a very elegant way of adding external dependencies through its config file. Would love to see something like that for Quasar!

                                1 Reply Last reply Reply Quote 0
                                • a47ae
                                  a47ae last edited by

                                  That is strange, If it works in a project generated by vue-cli it almost definitely should work in Quasar without much adaptations.
                                  The only difference is how you load the libraries (btw. also in plain Vue.js it is not recommended to load libraries by adding a script tag, because then you load this library on every page).

                                  If you want post your code and I can take a look at it when I have some spare time. 🙂

                                  1 Reply Last reply Reply Quote 0
                                  • First post
                                    Last post