2

In a VueJS component named GlobeInformation.vue, I would like to call a getter "mapData" which I expect to return a manipulated version of my state's data, however when I display it in my template it shows up as an empty array. I've posted a stripped down relevant version of my code below. Thanks in advance.

PS : I suppose this happens due to the async API call, hence I tried using v-if conditions to check if the data has been received only then render it on the template.

GlobeInformation.vue

<template>
<div class="information">
    <div v-if="mapDataLoaded">
        {{ mapInformation }}
    </div>
</div>
</template>
<script>
export default {
    data: function() { 
        return { 
            mapDataLoaded: false,
            mapInformation: []    
        }
    },
    computed: {
        ...mapGetters(['mapData'])
    },
    methods: {
        ...mapActions(['fetchCondensedDetails'])
    },
    async mounted() {
        await this.fetchCondensedDetails('/')
        this.mapInformation = await this.mapData
        this.mapDataLoaded = true
    }
}
</script>

getters.js

export default {
    mapData: state => {
        let mapData = []
        state.condensed.forEach(country => {
            mapData[country.alpha_2] = country.confirmed
        })
        return mapData
    }
}

actions.js

export default {
    async fetchCondensedDetails({ commit }, path) {
        try {
            if (path === '/') {
                const res = await fetch('https://covidapi.info/api/v1/global/latest')
                commit('SET_CONDENSED_DETAILS', await res.json())
            }
        } catch (err) {
            console.log(err)
        }
    }

}

mutations.js

export default {
    SET_CONDENSED_DETAILS: (state, data) => {
        data.result.forEach((element, index) => {
            const key = Object.keys(element)[0]

            let details = countries.find(country => {
                if (country.alpha_3 === key) return country
            })

            if (details) {
                state.condensed.push({
                    ...data.result[index][key],
                    alpha_3: key,
                    alpha_2: details.alpha_2,
                    name: details.name
                })
            }
        })
    }
}
2
  • Is country.alpha_2 a number? Commented Apr 11, 2020 at 12:22
  • @Anatoly yeah, country.alpha_2 is a number. Probably worth noting if I console.log this.mapInformation at the end of my mounted function I get the desired data, only doesn't work when rendering to a template. Commented Apr 11, 2020 at 13:04

1 Answer 1

1

We can't see the data structure of countries, so this is a bit of a guess, but should work as long as your data is properly unique. You can remove mapInformation and use the getter directly in the template:

<div v-if="mapDataLoaded">
  {{ mapData }}
</div>

Change the getter's mapData to an object:

mapData: state => {
  let mapData = {}; // <-- object instead of array
  ...
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you @dan, this works :) if you don't mind could you explain why an object works and an array doesn't?
Good :) you're welcome. I was working off the assumption that alpha_2 was a string rather than a number. In that case, the indexes used to set mapData in the getter's forEach would have been strings. If they're indeed numbers, it should work as an array.
Ah should have been clear about the datatype, that makes sense though, thank you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.