Your attempt at implementing the flow should be effective. There may be an error in a section that has not been shared. However, this approach deviates from the usual method of achieving the desired outcome.
An Alternative Approach
When there exists a parent-child relationship between components (e.g., Dashboard -> Applayout
), the conventional way to facilitate communication is by emitting events from the child component:
this.$emit('custom-event-name', { eventData: 'if needed' })
Subsequently, these events are captured and handled in the parent component as follows:
<Dashboard @custom-event-name="uploadDataToS3" />
This methodology promotes loose coupling between components, enabling seamless integration of additional components within the parent-child hierarchy. Moreover, it simplifies event monitoring through the Vue dev tools extension.
A More Sophisticated Solution
For scenarios where components function as siblings and data exchange is required, utilizing Vuex is recommended for its elegance and maintainability. Though initially complex, employing Vuex streamlines API calls and enhances code reusability across different components.
The implementation entails creating a store resembling the following structure:
import Vuex from 'vuex'
import axios from 'axios'
const store = new Vuex.Store({
state: {
neededData: '',
resultData: 0
},
mutations: {
setNeededData (state, payload) {
state.neededData = `Longitude: ${payload.lng}, Latitude: ${payload.lat}, Uncertainty Radius: ${payload.uncertainty_radius} meters, Address: ${payload.place_name}, Source: TEXT\n`
},
setResultData (state, payload) {
state.someData = payload
}
},
actions: {
async uploadDataToS3 (context, data) {
const result = await axios.post(
"http://localhost:8080/api/v1/targetLocation/uploadLocationsToS3Bucket",
context.state.neededData,
{headers: {'Content-Type': 'application/json'}}
)
context.commit('setResultData ', result.data)
}
}
})
export default store
To relay information from Dashboard
to the store, incorporate the following logic on the element interacting with the necessary data for API invocation:
<template>
<input type="text" v-model="dashboardData.lat" />
<input type="text" v-model="dashboardData.lng" />
<button type="button" @click="setData" />
</template>
<script>
export default {
data () {
return {
dashboardData: {
lat: '',
lng: ''
}
}
},
methods: {
setData () {
this.$store.commit('setNeededData', this.dashboardData)
}
}
}
</script>
For the Applayout
component, trigger the data upload action like so:
<button @click="$store.dispatch('uploadDataToS3', neededData)" />
Lastly, retrieve the result data back in the Dashboard
component using either of the following approaches:
<script>
import { mapState } from 'vuex'
export default {
computed: {
...mapState(['someData'])
}
}
</script>
or simply access the data directly:
this.$store.state.someData
I personally favor the former technique as it provides a clear overview of the retrieved data from the store within the computed property.