For some reason this was giving me trouble this morning, and I just couldn't figure out why it wouldn't work.
I have a variable 'applications' set equal to the data returned by my axios call. I want to include 'applications.name' as a field in my data() to send as a form. However when I try this, Vue gives me an error saying 'Cannot read property 'name' of undefined'.
{{applicants.name}} and {{applicants.role}} are working in the template, so I'm not just getting empty data
Also another thing, data() doesn't seem to recognize my 'this.loggedInUser.id' field either for some reason. (I've imported both Vuex and mapGetters)
Appreciate the help! :)
async asyncData({ $axios, params }) {
try {
let applicants = await $axios.$get(`/api/v1/apps/${params.id}/`);
return { applicants };
} catch (error) {
console.log(error);
return { applicants: [] };
}
},
data() {
return {
applicants: [],
application: {
name: this.applicants.name,
status: null,
company: null,
role: this.applicants.role
// user: this.loggedInUser.id
}
};
}
};
Try to pass this as parameter to the data property function:
data(vm) { //refers to this keyword
return {
applicants: [],
application: {
name: vm.applicants.name,
status: null,
company: null,
role: vm.applicants.role
// user:vm.loggedInUser.id
}
};
}
or make application as a computed property :
data() {
return {
applicants: [],
};
}
,
computed:{
application(){
return {
name: this.applicants.name,
status: null,
company: null,
role: this.applicants.role
// user: this.loggedInUser.id
}
}
}
I am assuming that when the data is initialized, the values applicants.name and loggedInUser.id do not exist. Try changing the data like this
data() {
return {
applicants: { name: '' },
application: {
name: this.applicants.name,
},
loggedInUser: { id: '' }
};
}
Related
I have created a plugin, created an admin route but inserting the data into Shopware 6 database does not work. Below is my code. After the build process, it doesn't work, what am I doing wrong?
From the code below I am trying to insert the data 'Diekedie' into the 'name' column of the 'product_manufacturer_translation' table.
const { Component, Mixin } = Shopware;
import template from './custom-module-list.html.twig'
Component.register('custom-module-list', {
template,
inject: [
'repositoryFactory'
],
metaInfo() {
return {
title: this.$createTitle()
};
},
data: function () {
return {
entity: undefined
}
},
methods: {
manufacturerRepository() {
return this.repositoryFactory.create('product_manufacturer_translation');
}
},
computed: {
},
created() {
this.manufacturerRepository();
this.entity = this.manufacturerRepository.create(Shopware.Context.api);
this.entity.name = 'Diekedie';
this.manufacturerRepository.save(this.entity, Shopware.Context.api);
}
});
To set translations you use the repository of the related entity, not the repository of the translations themselves. Also if you have a method that returns the created repository, you must use that return value to create the entity:
methods: {
manufacturerRepository() {
return this.repositoryFactory.create('product_manufacturer');
},
},
created() {
const repository = this.manufacturerRepository();
this.entity = repository.create(Shopware.Context.api);
this.entity.name = 'Diekedie';
repository.save(this.entity, Shopware.Context.api);
}
My goal is to initially set up a data property when component is created and then set up a watcher on this property. The issue I am struggling with is the watcher catches initial property change in created method but this is not what I want. I would rather to watch data property only after initial change is made in created().
export default {
name: 'testComponent',
data() {
return {
testValue: 1;
}
},
watch: {
testValue() {
console.log('watcher catches!');
},
created() {
console.log(this.testValue);
this.testValue = 2;
console.log(this.testValue);
}
}
// CONSOLE OUTPUT: 1 -> watcher catches! -> 2
Can you tell me how to achieve behaviour like that?
No idea why you'd want that but you could simply do it like this:
export default {
name: 'testComponent',
data() {
return {
ready: false,
testValue: 1
}
},
watch: {
testValue() {
if (!this.ready) return;
console.log('watcher catches!');
},
created() {
this.testValue = 2;
this.ready = true;
}
}
I tried to provide my data from a parent element like below.
data(){
return{
allData:null,
ingCollection:null,
selectedDish:[]
}
},
mounted(){
Promise.all([
d3.json('data.json'),
d3.json('ingredientsonly.json')
]).then((data)=>{
this.allData=data[0];
this.ingCollection=data[1];
})
},
components:{sidePanel,centerPiece},
methods: {
// receiveIngredients(selected){
// let selections = this.allData.filter(d=>{
// d.ingredients.includes(selected)
// });
// }
},
provide() {
return{
allData:this.allData,
ingCollection:this.ingCollection,
selectedDish:this.selectedDish,
receiveIngredients:this.receiveIngredients
}
}
However, after mounted lifecycle hook was run,
data is updated while provide elements were not updated.
Why is it?
Thank you
provide() is only called once at initialization, and not when there's a change to the references within.
Instead, you can provide an object (e.g., named root), and then update a property of that object in mounted():
export default {
provide() {
return {
root: {
allData: null,
ingCollection: null,
}
}
},
mounted() {
Promise.all([
d3.json('data.json'),
d3.json('ingredientsonly.json')
]).then((data)=>{
this.root.allData = data[0];
this.root.ingCollection = data[1];
})
}
}
my intention is to get some data from api,
then put in the head(){} to set description and title,
but it keep telling me val.replace is not a function,
here is my code
async mounted() {
...await call api...
if (resDataGetNewsInfo.return_code === 0) {
vm.newsInfoObj = resDataGetNewsInfo.return_msg;
} else {
...
}
...
asyncData() {
return {
newsInfoObj: '',
};
},
...
head() {
return {
description: this.newsInfoObj.news_short_desc,
meta: [
{
hid: 'og:title',
property: 'og:title',
content: this.newsInfoObj.news_title,
},
Uncaught TypeError: val.replace is not a function
thanks for answering
Thats not the way to use asyncData.
Your API call should be called inside the asyncData and then return your data
In my vue screen I'd like to use one apollo graphql I've defined for two properties. As far as I understand the name of the property must match a name of the attribute in the returned json structure.
I naivly tried to use the queries for two properties but it throws an error for the second one.
...
data() {
return {
userId: number,
user: null as User | null,
previousUserId: number,
previousUser: null as User | null
};
},
...
apollo {
user: {
query: READ_ONE_USER,
variables() {
return {
userId: this.userId
};
}
},
previousUser: {
query: READ_ONE_USER,
variables() {
return {
userId: this.previousUserId
};
},
export const READ_ONE_USER = gql(`
query user($userId: Int!) { user(userId: $userId)
{
id
firstName
lastName
email
}
}
`);
I expected no problems but I get "Missing previousUser attribute on result {user: ...}"
Daniel's solution didn't work out for me, I still got the same error message.
But there's another way to do it, you can provide an update function to tell apollo how to extract the result out of the data read from the server:
apollo {
user: {
query: READ_ONE_USER,
variables() {
return {
userId: this.userId
};
}
},
previousUser: {
query: READ_ONE_USER,
variables() {
return {
userId: this.previousUserId
};
},
update(data) {
return data.user;
}
}
This is documented at https://github.com/vuejs/vue-apollo/blob/v4/packages/docs/src/api/smart-query.md#options
As shown in the docs, you can manually add smart queries inside the created hook:
created () {
this.$apollo.addSmartQuery('user', {
query: READ_ONE_USER,
variables() {
return {
userId: this.userId
};
},
})
this.$apollo.addSmartQuery('previousUser', {
query: READ_ONE_USER,
variables() {
return {
userId: this.previousUserId
};
},
})
}