I'm fetching some data like so:
Vue.createApp({
data(){
object: {},
},
...
mounted() {
fetch("{SERVER_URL}/someurl.php?=getObject")
.then((response) => response.json())
.then((data) => {
this.object = data;
}
...
}
Then, in the html I do the following
<div>{{object.parent.child}}</div>
Which returns
Uncaught TypeError: Cannot read properties of undefined (reading 'child')
While {{translations.parent}} correctly returns the parent object.
This is what the object looks like;
{
"parent": {
"child": "value",
...
},
...
}
How can I correctly retrieve the child' value?
Before you fetch your data from server, your object doesn't have the parent attribute / key, but you are trying to access it. So, improve your code this way:
<div>{{object.parent?.child}}</div>
or this way, if you want to have more backwards compatible code:
<div>{{object.parent && object.parent.child}}</div>
Related
I need help. I'm kind of an amateur in Vue3, and canĀ“t understand why this happens:
If I set this in the parent component:
props: [ 'code' ],
data() {
return {
asset: {
id: '',
brand: '',
group: {
name: '',
area: ''
}
}
}
},
created() {
axios.get('/api/myUrl/' + this.code, {})
.then(response => {
if (response.status === 200) {
this.asset = response.data;
}
})
.catch(error => {
console.log(error);
})
}
then, in my component <asset-insurance :asset_id="asset.id"></asset-insurance>, asset_id prop is empty.
But, if I set:
props: [ 'code' ],
data() {
return {
asset: []
}
},
created() {
axios.get('/api/myUrl/' + this.code, {})
.then(response => {
if (response.status === 200) {
this.asset = response.data;
}
})
.catch(error => {
console.log(error);
})
}
then, the asset_id prop gets the correct asset.id value inside <asset-insurance> component, but I get a few warnings and an error in the main component about asset property group.name not being set (but it renders correctly in template).
Probably I'm doing something terribly wrong, but I can't find where is the problem. Any help?
Edit:
I'm checking the prop in child component AssetInsurance just by console.logging it
<script>
export default {
name: "AssetInsurance",
props: [
'asset_id'
],
created() {
console.log(this.asset_id)
}
}
</script>
asset_id is just an integer, and is being assigned correctly in parent's data asset.id, because I'm rendering it in the parent template too.
It's incorrect to define asset as an array and reassign it with plain object. This may affect reactivity and also prevents nested keys in group from being read.
The problem was misdiagnosed. asset_id value is updated but not at the time when this is expected. Prop value is not available at the time when component instance is created, it's incorrect to check prop value in created, especially because it's set asynchronously.
In order to output up-to-date asset_id value in console, a watcher should be used, this is what they are for. Otherwise asset_id can be used in a template as is.
Ok, I think I found the proper way, at least in my case.
Prop is not available in the component because it is generated after the creation of the component, as #EstusFlask pointed.
The easy fix for this is to mount the component only when prop is available:
<asset-insurance v-if="asset.id" :asset_id="asset.id"></asset-insurance>
This way, components are running without problem, and I can declare objects as I should. :)
Thank you, Estus.
I have code like this for a store in Vuex, if do it like the code below it works fine.
state: {
APIData: {},
},
getters: {
getFeed: state => {return state.APIData },
},
mutations: {
SET_FEED_DATA(state, {folder_id, data}) {
state.APIData = data
}
},
However, if I try to use a key to set and get the value it return undefined in the getter. I want to do this because I have a for loop in my template calling an action multiple times but with different id's that I will use here for the key value.
state: {
APIData: {},
},
getters: {
getFeed: state => {return state.APIData["test"] },
},
mutations: {
SET_FEED_DATA(state, {folder_id, data}) {
state.APIData["test"] = data
}
},
Edit
Looking in Vue debugger I find the following, so it seems the mutation is setting that data but the getter can access it.
Inside the mutation, try to set it like below:
state.APIData = { ...state.APIData, test: data };
The getter is for APIData and it will not recognize the change if you update an individual property directly. You need to reset the whole APIData object.
To replace the test with a variable:
state.APIData = { ...state.APIData, [VARIABLE_NAME]: data };
For example, if you want to pass the key name as folder_id in your code:
state.APIData = { ...state.APIData, [folder_id]: data };
everyone. I'm working on a project and I'm stuck on a particular point. On the backend side, I'm using Laravel 5.6 and MySQL. I make a request that returns a simple JSON like this:
{
id: 1,
name: "someone",
salary_min: 2600.5,
salary_max: 3512.35
}
And I fecth this result in the frontend using Vue + axios like any other GET request and assign to a list of employees.
this.axios.get(process.env.ROOT_API + 'employee/${id}', auth)
.then(response => {
if (response.data) {
this.employee = response.data;
}
}, (error) => {
console.log(error.response.data);
});
I'm passing this data to another child component througn a method defined like so:
onEdit (id) {
// Send data received from axios and stored in 'emmployee'
bus.$emit('editEmployee', this.employee);
}
Inside the child component, I'm listening to the event like this:
mounted () {
bus.$on('editEmployee', (data) => {
console.log(data);
this.newEmployee = data;
console.log(this.newEmployee);
}
}
The result of log is as following:
// data from parent component
{ id: 1, name: "someone", salary_min: 2600.5, salary_max: 3512.35 }
// newEmployee model
{ id: 1, name: "someone", salary_min: "0.00", salary_max: "0.00" }
Somehow, during assignment, the decimal values are being zeroed and converted to string. I can't understand what's happening. Any clue?
Using axios to fetch api data:
fetchData () {
axios.get(globalConfig.OFFERS_URL)
.then((resp) => {
this.offersData = resp.data
console.log(resp)
})
.catch((err) => {
console.log(err)
})
}
Data function:
data () {
return {
offersData: {}
}
}
Now i can use fetched data in my template, like so: {{ offersData.item[0].id }}
But can i set the fetched data in a data function:
data () {
return {
offersData: {},
id: this.offersData.item[0].id
}
}
It's not working for me, is that even possible to store axios get's response in a data function?
You probably are looking for computed property:
data () {
return {
offersData: {},
}
},
computed() {
id() {
return this.offersData.item && this.offersData.item[0].id;
}
}
As for data function, it is used to define shape of state (set up the properties to be tracked) of component and give valid initial values to it. In this case, however, id should neither be a part of state (it's always a part of offersData value, after all) nor its initial value can be calculated before offersData is set up by a remote call.
I am using the vue-form-generator component. I am attempting to update a variable in the store with the response from a call back. What I believe the relevant code is (inside the schema:fields property):
{
type: 'submit',
buttonText: 'Save Updates',
styleClasses: ['custom-submit', 'custom-submit-primary', 'custom-submit-full'],
disabled () {
return this.errors.length > 0
},
validateBeforeSubmit: true,
onSubmit: function (model, schema) {
Vue.CustomSubmit('UserUpdate', model).then((response) => {
this.$store.user = response
})
}
}
From within the Vue.CustomSubmit().then((response)) => { ... }
I don't seem to be able to access the store.
It works slightly higher in scope, such as:
data () {
return {
avatar: this.$store.getters.user.avatar,
...
}
You cannot modify the $store directly. That's the most important part of the vuex concept. You need to use a mutation and commit it after you got the data.
Here it is described https://vuex.vuejs.org/en/mutations.html