Async Vuex problemen..

Pagina: 1
Acties:

Vraag


Acties:
  • +1 Henk 'm!

  • RoelZ
  • Registratie: Oktober 2005
  • Laatst online: 18-09 13:35
Voor een eigen project probeer ik de data in mijn store van Vuex te tonen in een component.
Deze eenvoudige denkwijze lijkt niet op te gaan wanneer de state muteer via een async action.

Nou hoop ik dat iemand snel de doorn weet te vinden.
Om alles wat leesbaarder te maken deel ik even een gestripte versie van mijn code.

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
state: {
resume: []
},

mutations: {
  SET_RESUME_DATA (state, payload) {
    state.resume = [...payload]
  },
}

actions: {
  async setResume ({ commit }, id){
    const response = await axios.get("api/cv");
    const currentResume = response.data.find((resume) => { return resume.id === id });
    commit('SET_RESUME_DATA', currentResume)
  }
}

getters: {
  showCurrentResume (state) {
    return state.resume
  }
}


Bij het laden van een parent component stuur ik een dispatch.

JavaScript:
1
2
3
created() {
  this.$store.dispatch("setResume", this.cvid );
}


Ik probeer vervolgens de store te raadplegen in een child component
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
<template>
  <pre>{{currentResume}}</pre>
</template>

<script>
export default {
  computed: {
    ...mapGetters({ currentResume: 'showCurrentResume'})
  }
}
</script>



Ik zie dus dat de store wordt geupdate (door elke stap te loggen)
Maar dat mijn resume.vue eerder opgebouwd is waardoor hij "te vroeg" is met het uitpoepen van de store.state

Echter dacht ik te begrijpen dat het reactive was (wat ik ook zie), maar het blijft een lege Array.

Ik heb het ook geprobeerd met, wat mij ook geen ander resultaat geeft
getCurrentResume(){
      return this.$store.getters.showCurrentResume
    }



Ik hoop dat iemand hier direct ziet welke domme fout ik maak... 8)7
Alvast daarvoor enorme dank! _/-\o_

- Creating more joy for people who interact with our digital world

Beste antwoord (via RoelZ op 24-12-2020 15:42)


  • OverloadOfRed
  • Registratie: Maart 2010
  • Laatst online: 01-10 22:22

OverloadOfRed

Bla, blabla

Hm. Dan zie ik niet zo gauw wat er fout gaat.
Wat heb je nog meer geprobeerd? Ik zou tenminste dit even nalopen:
- Checken of data überhaupt wel uit de store komt. Zet er eens default een string oid in en check of de value nog steeds een lege array is.
- Checken of de data wel doorkomt als je er een input met vmodel of :value='currentResume' van maakt
- Checken of de state wel wordt updated, met de vue browser plugin de state wel goed staat en wat er precies in het child component voor computed props worden berekend
- En misschien wel het belangrijkst: checken wat er in de action gebeurt. Gaan de promises wel goed, worden ze resolved, krijg je de data of wordt er een error gegooid die je niet ziet etc

Ik ben chatman, supersnel met MSN. Er is niemand die me niet kent

Alle reacties


Acties:
  • 0 Henk 'm!

  • OverloadOfRed
  • Registratie: Maart 2010
  • Laatst online: 01-10 22:22

OverloadOfRed

Bla, blabla

Gebruik je de spread op de mutation wel goed? Ik gebruik zelf Vuex alleen met Typescript en wat meer 'basic' code zonder spread operators, maar als ik zo snel google gaat die mutation niet goed.

Probeer eens de state direct te zetten met de inhoud van je payload, zoiets:
JavaScript:
1
2
3
4
5
mutations: {
  SET_RESUME_DATA ({ state }, payload) {
    state.resume = [ payload ];
  },
}

Ik ben chatman, supersnel met MSN. Er is niemand die me niet kent


Acties:
  • 0 Henk 'm!

  • RoelZ
  • Registratie: Oktober 2005
  • Laatst online: 18-09 13:35
OverloadOfRed schreef op woensdag 23 december 2020 @ 21:24:
Gebruik je de spread op de mutation wel goed? Ik gebruik zelf Vuex alleen met Typescript en wat meer 'basic' code zonder spread operators, maar als ik zo snel google gaat die mutation niet goed.

Probeer eens de state direct te zetten met de inhoud van je payload, zoiets:
JavaScript:
1
2
3
4
5
mutations: {
  SET_RESUME_DATA ({ state }, payload) {
    state.resume = [ payload ];
  },
}
Bedankt voor je vlotte antwoord.
Helaas had ik dit ook al geprobeerd, door bijv. state.resume.id = payload.id

Het is ook niet dat de state van de store niet gevuld wordt. Dit zie ik wel gebeuren.
Alleen is het hele async timing/opbouw bij mij verkeerd vrees ik. Maar ik krijg het maar niet goed uitgewerkt

- Creating more joy for people who interact with our digital world


Acties:
  • Beste antwoord
  • +1 Henk 'm!

  • OverloadOfRed
  • Registratie: Maart 2010
  • Laatst online: 01-10 22:22

OverloadOfRed

Bla, blabla

Hm. Dan zie ik niet zo gauw wat er fout gaat.
Wat heb je nog meer geprobeerd? Ik zou tenminste dit even nalopen:
- Checken of data überhaupt wel uit de store komt. Zet er eens default een string oid in en check of de value nog steeds een lege array is.
- Checken of de data wel doorkomt als je er een input met vmodel of :value='currentResume' van maakt
- Checken of de state wel wordt updated, met de vue browser plugin de state wel goed staat en wat er precies in het child component voor computed props worden berekend
- En misschien wel het belangrijkst: checken wat er in de action gebeurt. Gaan de promises wel goed, worden ze resolved, krijg je de data of wordt er een error gegooid die je niet ziet etc

Ik ben chatman, supersnel met MSN. Er is niemand die me niet kent


Acties:
  • +1 Henk 'm!

  • analogue
  • Registratie: Augustus 2010
  • Laatst online: 02-10 08:39
Misschien vergezocht, maar onlangs was ik met iets dergelijks in aanraking gekomen en toen hielp het wanneer ik de dispatch in de beforeMount() van mijn component aanriep.

code:
1
2
3
      beforeMount() {
          this.$store.dispatch('getData')
      }

Acties:
  • +1 Henk 'm!

  • Jacob de Keizer
  • Registratie: November 2015
  • Laatst online: 28-09 18:56
Het kan zijn dat de store reactivity verliest. Om reactivity the behouden moet je Vue.set gebruiken, zie: https://vuex.vuejs.org/gu...ow-vue-s-reactivity-rules

Je kunt de mutation dan veranderen naar:
code:
1
Vue.set(state, 'resume', payload)

Daarnaast kun je met de vue devtool bekijken of de mutations op je vuex store juist zijn.

  • RoelZ
  • Registratie: Oktober 2005
  • Laatst online: 18-09 13:35
Alemaal bedankt voor jullie antwoorden (en tijd)!

Omdat ik jullie feedback een-voor-een wilde nalopen (en evt. kon delen) had ik even een demo projectje opgezet. Omdat ik hier even alle overtollige dingen kon weg laten en de axios.get had vervangen voor een setTimeout Promise, raakte ik eigenlijk al de gevoelige snaar. Iets waar @OverloadOfRed me ook op wees.

Er ging blijkbaar iets mis met het doorsturen/muteren van de opgehaalde data.
Omdat de Promise van axios niet alleen de data terug geeft, maar ook alles van de request was de mapping naar mijn store.state.resume verkeerd.
Note de blokhaken [ currentResume ] !

actions
code:
1
2
3
4
5
async setResume ({ commit }, id){
   const response = await axios.get("api/cv");
   const currentResume = response.data.find((resume) => { return resume.resume_id === id });
   commit('SET_RESUME_DATA', [currentResume])
}


mutations
code:
1
2
3
SET_RESUME_DATA (state, payload) {
   state.resume = payload
},


Bovenstaande werkt dus!
En ik zag dus dat ik in mijn OP niet helemaal eerlijk ben geweest, ik had mijn mutation namelijk nog als volgt staan.. wat inderdaad de boosdoener was mbt het mappen.

code:
1
2
3
4
5
UPDATE_RESUME_DATA (state, payload) {
   state.resume.id = payload.data.resume_id
   state.resume.template_id = payload.data.resume_template_id
   state.resume.language = payload.data.resume_language
},


Enorm bedankt voor het mee denken!

[ Voor 5% gewijzigd door RoelZ op 24-12-2020 15:53 ]

- Creating more joy for people who interact with our digital world


  • RoelZ
  • Registratie: Oktober 2005
  • Laatst online: 18-09 13:35
Ook wil ik apart @analogue bedanken voor de heads-up.
Er ging namelijk nog wel iets verkeerd in mijn flow. Echter werk ik met Vue 3.

Ik heb het nu even nagelopen en heb van het onderstaande (wat nog helemaal verkeerd was)
code:
1
2
3
4
5
6
7
8
export default {
props: ['cvid'],
  created(){
    if(!isNaN(props.cvid)){
      store.dispatch("setResume", props.cvid );
    }
  }
}


dit gemaakt. Wat dus 100x beter is (en eigenlijk gewoon zo moet)!

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { onBeforeMount } from 'vue'
import { useStore } from 'vuex'

export default {
props: ['cvid'],
  setup(props) {
    const store = useStore();
    onBeforeMount(() => {
      if(!isNaN(props.cvid)){
        store.dispatch("setResume", props.cvid );
      }
    })
  }
}


Thank you!

- Creating more joy for people who interact with our digital world

Pagina: 1