Hi,
Regarding this:
Make the API call in the asyncData() or fetch() methods of the page component and pass the data as props to the sub components. Server rendering will work fine.
(https://nuxtjs.org/faq/async-data-components#async-data-in-components-)
The point is, I have a component that shall work for every page ; so I call it directly in the layout, so it’s not reloaded at each page load. This composent has a google map, the position / zoom / etc. shouldn't change from one page to another ; it has to be visible and usable at any time, regardless where you are on the site. Basically, it's like an interactive background.
But it contains markers, that are loaded from a rest API, so I need to get them through asyncData
; and I can’t do it directly on the layout too and pass the data as a props…
How should I proceed?
Thanks.
You should probably use nuxtServerInit
to fetch the app's initial data: https://nuxtjs.org/guide/vuex-store#the-nuxtserverinit-action
Ha, then I’ll have to dig out Vuex… I've avoid it as long as I could. Not sure to understand clearly how it works, but I’ll get through the docs.
So, I shall have my async axios call in the store, then use its datas in the module, right?
Thanks!
Exactly! :)
Vuex is awesome, you're gonna love it!
Okay, I managed to have it to work, but I can’t find how to fill the base state with content.
Here’s what I have in store/map.js
(I chose the module way):
import axios from 'axios'
export const state = () => ({
markers: null
})
axios.get('http://rest.api.localhost/spots')
.then((res) => {
state.markers = res.data
})
export const mutations = {
list (state, marker) {
state.markers.push(marker)
}
}
res.data
contains the data from the rest api, but the markers object still has null
value. How am I supposed to init this content?
Thanks again, vuex seems indeed powerful and useful! Reading from the examples, I already got how I’ll be able to add new user functions.
Edit: Okay, I think I get that I should create a function (like an init) and then call it from my template, right? More like this:
import axios from 'axios'
export const state = () => ({
markers: null
})
export const mutations = {
init (state) {
axios.get('http://rest.api.localhost/spots')
.then((res) => {
state.markers = res.data
})
},
list (state, marker) {
state.markers.push(marker)
}
}
But then how to fire it? The example make use of fetch()
method, but like asyncData()
, it only work in pages components.
https://nuxtjs.org/guide/vuex-store go down to the nuxtserverinit section.
Thanks!
Regarding this page:
If you are using the Modules mode of the Vuex store, only the primary module (in store/index.js) will receive this action. You'll need to chain your module actions from there.
I feel the doc would really need an explanation and an example here. Chain the modules actions? How do I do that?
I’ll gladly improve this section as soon as I’ll understand, but I need to understand first. Can you explain it to me? Thanks!
Also, this portion of code isn’t firing at all in store/index.js
export const actions = {
nuxtServerInit ({ commit }) {
console.log(commit)
}
}
Found this similar issues (and this particular answer), but even with just copy-pasting the code basically, it wont work for me; even less than what I got at the moment.
Hi @EmmanuelBeziat,
Have you tried with this code?
export const state = () => ({})
export const getters = {}
export const mutations = {}
export const actions = {
async nuxtServerInit ({ commit }, { req }) {
console.log('server init')
}
}
@alexchopin hi,
Yes, and I just tried to copy-paste directly your code example, but the console never shows 'server init'. Yet, any element defined in state (even in a module store file) is applied in the store, so nothing seems wrong with vuex.
Thanks
Note that logging stuff in nuxtServerInit
won't show in the browser's console since it's called server-side, it should show in the terminal where you ran the app though.
@paulgv Oh for f.‘s sake, you’re right… How can I be so dumb, I didn’t even checked this. It shows in the console. Much thanks!
Well, I still need to figure how to fire action from another file. Slowly going there… Any thoughts?
Thanks again!
@EmmanuelBeziat I think we should specify it in the documentation, it can be obvious or not :)
You can use dispatch in your nuxtServerInit like this:
export const actions = {
async nuxtServerInit ({ dispatch }, { req }) {
await dispatch('MODULE/ACTION')
}
}
I’m willing to improve this page of the documentation as soon as I understand what’s going on there. :)
Well, I’m using the modules way, and I have this file store/map.js
:
import axios from 'axios'
const api = 'http://rest.api.localhost/spots'
export const state = () => ({
markers: null
})
export const mutations = {
init (state) {
axios.get(api)
.then((res) => {
state.markers = res.data
})
}
}
export const actions = {
init ({ commit }) {
commit('init')
}
}
(I’m not sure if the axios call should be in mutations or action, though).
So from store/index.js
, I’d like to call this init action to load my datas, as specified in the doc about nuxtServerInit:
If you are using the Modules mode of the Vuex store, only the primary module (in
store/index.js
) will receive this action. You'll need to chain your module actions from there.
I just don’t know how I should do it.
Thanks again!
@alexchopin Oh, I didn’t see your edit. Thanks! That's okay, I can now fire the "init" actions, that nicely start the "init" mutation. Great!
Now the problem is here:
export const mutations = {
init (state) {
axios.get(api)
.then((res) => {
state.markers = res.data
console.log(state.markers)
})
}
}
The console.log nicely report all the datas I need, but still, the markers object is still damn empty…
Anyway, thanks again.
I have some problem too , help please kind people ;)
@EmmanuelBeziat
store/map.js
import axios from 'axios'
const api = 'http://rest.api.localhost/spots'
export const state = () => ({
markers: null
})
export const mutations = {
SET_MARKERS (state, markers) {
state.markers = markers
}
}
export const actions = {
async init ({ commit }) {
let { data } = await axios.get(api)
commit('SET_MARKERS', data)
}
}
Aaand it worked amazingly. A huge thanks.
I think I get it better: The action is the one that gather datas, then send it to a mutation… I understand. I couldn’t find any good explanation of what purpose the actions has in this case on the vuex docs…
Again, thanks. I’ll make a pull request to illustrate this on the doc page.
@EmmanuelBeziat can you show code from pages/_vue , how get init actions? thanks
@andysay Check my repo, everything’s in it! :)
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Most helpful comment
@EmmanuelBeziat
store/map.js