1

Context: I am trying to get Google Maps place data via the place_id on the beforeEnter() route guard. Essentially, I want the data to load when someone enters the url exactly www.example.com/place/{place_id}. Currently, everything works directly when I use my autocomplete input and then enter the route but it does not work when I directly access the url from a fresh tab. I've been able to solve this using the beforeEnter() route guard in traditional Vue, but cannot solve for this using Nuxt. Please help!

Question: How can I access the Vuex Store before a page loads in Nuxt?

Error: Any solution I try (see below) I either end up with a blank page or the page will not load (I think it is stuck in a loop and cannot resolve the Promise).

Attempted Solutions:

  1. Using Middleware like below:
  middleware({ store, params }) {
    return store.dispatch('myModule/fetchLocation', params.id)
  }
  1. Using asyncData like below:
data(){
  return{
    filteredLocation: {}
  }
}

// snip

async asyncData({ store, params }) {
  const { data } = await store.dispatch('myModule/fetchLocation', params.id)
  return filteredLocation = data
}
  1. I tried looking into fetch, but apparently you no longer have access to context

Example Code:

In one of my store modules:

/* global google */

import Vue from 'vue'
import * as VueGoogleMaps from '~/node_modules/vue2-google-maps/src/main'

Vue.use(VueGoogleMaps, {
  load: {
    key: process.env.VUE_APP_GMAP_KEY,
    libraries: 'geometry,drawing,places'
  }
})

export const state = () => ({
  selectedLocation: {}
})

export const actions = {
  fetchLocation({ commit }, params) {
    return new Promise((resolve) => {
      Vue.$gmapApiPromiseLazy().then(() => {
        const request = {
          placeId: params,
          fields: [
            'name',
            'rating',
            'formatted_phone_number',
            'geometry',
            'place_id',
            'website',
            'review',
            'user_ratings_total',
            'photo',
            'vicinity',
            'price_level'
          ]
        }
        const service = new google.maps.places.PlacesService(
          document.createElement('div')
        )
        service.getDetails(request, function(place, status) {
          if (status === 'OK') {
            commit('SET_PLACE', place)
            resolve()
          }
        })
      })
    })
  }
}

export const mutations = {
  SET_PLACE: (state, selection) => {
    state.selectedInstructor = selection
  }
}

EDIT: I already have it in a plugin named google-maps.js and in my nuxt.config.js file I have:

  plugins: [
    { src: '~/plugins/google-maps.js' }
  ]
//
//
  build: {
    transpile: [/^vue2-google-maps.js($|\/)/],
    extend(config, ctx) {}
  }
James Murray
  • 23
  • 1
  • 6

1 Answers1

-1

Using Middleware is how we can access Vuex before page loads. try putting the configuration part in a custom Nuxt plugin. Create a file in Plugins folder (you can name it global.js). Put this

import Vue from 'vue'
import * as VueGoogleMaps from '~/node_modules/vue2-google-maps/src/main'

Vue.use(VueGoogleMaps, {
 load: {
  key: process.env.VUE_APP_GMAP_KEY,
libraries: 'geometry,drawing,places'
}
})

in global.js. Then add the plugin in nuxt.config.js like this.

 plugins: [
  '~/plugins/global.js' 
 ]

Also, make sure you're using underscore before 'page_id' name in your folder structure.

mostafa
  • 324
  • 2
  • 8
  • Sorry this was not mentioned in the initial post (i've since edited). I already have it in a plugin named `google-maps.js` and in my `nuxt.config.js` file I have: ```javascript plugins: [ { src: '~/plugins/google-maps.js' } ] // // build: { transpile: [/^vue2-google-maps.js($|\/)/], extend(config, ctx) {} } ``` – James Murray Jun 20 '20 at 22:53