How to pass an array of objects to child component in VueJS 2.x - vue.js

I am trying to send an array containing arrays which in turn contains objects to one component from another, but the content from the array seems to be empty in the child component.
I have tried sending the data as a String using JSON.Stringify() and also as an array
My parent component:
data: function(){
return{
myLineItems : []
}
},
created(){
this.CreateLineItems();
},
methods:{
CreateLineItems(){
let myArrayData = [[{"title":"Title1","value":2768.88}],[{"title":"Title2","value":9}],[{"title":"Title3","value":53.61},{"title":"Title4","value":888.77},{"title":"Title5","value":1206.11},{"title":"Title6","value":162.5}]]
this.myLineItems = myArrayData;
}
}
My parent component's template:
/*
template: `<div><InvoiceChart v-bind:lineItems="myLineItems"></InvoiceChart></div>`
My child component:
const ChildComponent= {
props: {
lineItems: {
type: Array
}
},
mounted() {
console.log(this.lineItems);
}
};
The parent component is created as so (inside a method of our main component):
var ComponentClass = Vue.extend(InvoiceDetails);
var instance = new ComponentClass({
propsData: { invoiceid: invoiceId }
});
instance.$mount();
var elem = this.$refs['details-' + invoiceId];
elem[0].innerHTML = "";
elem[0].appendChild(instance.$el);
If I try to do a console.log(this) inside the childcomponent, I can see the correct array data exist on the lineItems property..but i can't seem to access it.
I have just started using VueJS so I haven't quite gotten a hang of the dataflow here yet, though I've tried reading the documentation as well as similar cases here on stackoverflow to no avail.
Expected result: using this.lineItems should be a populated array of my values sent from the parent.
Actual results: this.lineItems is an empty Array
Edit: The problem seemed to be related to how I created my parent component:
var ComponentClass = Vue.extend(InvoiceDetails);
var instance = new ComponentClass({
propsData: { invoiceid: invoiceId }
});
instance.$mount();
var elem = this.$refs['details-' + invoiceId];
elem[0].innerHTML = "";
elem[0].appendChild(instance.$el);
Changing this to a regular custom vue component fixed the issue

Code - https://codesandbox.io/s/znl2yy478p
You can print your object through function JSON.stringify() - in this case all functions will be omitted and only values will be printed.

Everything looks good in your code.
The issue is the property is not correctly getting passed down, and the default property is being used.
Update the way you instantiate the top level component.

Try as below =>
const ChildComponent= {
props: {
lineItems: {
type: Array
}
},
mounted() {
console.log(this.lineItems);
}
};

Related

All values getting upadted when tried to update single element in an associative array in Vue 3

I have the below code in Vue3:
data: function() {
return {
testData:[],
}
},
mounted() {
var testObj = {
name: 'aniket',
lastname: 'mahadik'
}
for (let index = 0; index < 3; index++) {
this.testData.push(testObj);
}
},
methods: {
updateLastName: function(key) {
this.testData[key].lastname = 'kirve';
}
}
When I call updateLastName(1) to update the lastname of only the second element, it's updating the lastname of all the elements.
I tried several ways but found no desired result.
Can someone point out to me what is going wrong here?
It is because you are pushing the reference to the same object in the array so when you update any item in the array you are instead updating every item since it reference the same object.
Either push by cloning the object :
testData.value.push({...testObj})
Or put the definition in the push
testData.value.push({ name: 'aniket', lastname: 'mahadik' })
Is JavaScript a pass-by-reference or pass-by-value language?

How to use state in data function in vue

Having problem to use state in data function of Vue.
I tried this
this.items = this.$store.state.search_items
but it always results in an empty array like this
[__ob__: Observer]
length: 0
__ob__: Observer {value: Array(0), dep: Dep, vmCount: 0}
__proto__: Array
Any help would be appreciated. Thank you !!
Here is the mutation from which I am stating search_items
this is working because I am able to see state.search_items in Vue dev tool
SET_WORKSPACES(state, payload) {
state.workspaces = payload;
var items = [];
if (state.workspaces.length) {
state.workspaces.forEach(function(workspace) {
// Adding workspaces
if (workspace.portfolios.length) {
items = [...items, ...workspace.portfolios];
}
// Adding projects
if (workspace.projects.length) {
items = [...items, ...workspace.projects];
// Adding tasks
workspace.projects.forEach(function(project) {
if (project.tasks.length) {
items = [...items, ...project.tasks];
}
});
}
});
}
state.search_items = items;
}
Data property
data() {
return {
results: [],
keys: ['title','description'],
list:this.items,
}
},
If the state is updating correctly, the time taking for setting the state is making the issue. That means, the the function you're using to assign the state to data is rendering before the state set.
You can use a computed function that returning the state
computed:{
items : function(){
return this.$store.state.search_items;
}
}
Now you can use the computed function name items same like a data variable.

How to declare an array outside function in vue's component syntax

I want to declare a global array inside vue.js component, so that I can access it in all the methods. Where do I declare it in which part of component?
I have tried setting in PROPS but it produces an object while I need an array type.
export default{
name:"BarElement",
props:[
"labels",
"dataset",
"colors"
],
methods:{
drawGraph() {
var dataPoints =[];
var dataPoint =this.getDataPoint(upperLeftCornerX,nextX,value);
this.dataPoints.push(dataPoint);
}
getDataPoint(x, nextX, value) {
return {
'leftEdge':x,
'rightEdge':nextX,
'value':value
}
},
showToolTip(event) {
var mouseX = event.offsetX;
var toolTipVal = this.dataPoints.forEach(function(item, key) {
if(mouseX >= item.leftEdge && mouseX <= item.leftEdge )
return item.value;
});
console.log(toolTipVal);
}
}
Try to declare it inside the data object
data () {
myArray:[]
}
You can also declare props as an object, as this will allow to specify the type of the props
props: {
labels: Array,
dataset: Array,
colors: Object
}
If you want all your components of that type to share the same array, declare it outside of the export default statement.
Well, Inside your component you can declare with data as function and that will be locally to your function.
name: "BarElement",
props: ["labels", "dataset", "colors"],
data: function() {
return {
foo: {
text: 'text1'
}
}
}
In case If you want to declare a global array in your app component.
Similar to the component, you can able to add the data inside it.
Now, to access that data, you can use it with this.$root.[nameOfObject].
Here are the official docs for $root
Hope this helps!

Vue js update array

data: {
addItemArray: [],
}
I have initialize one array inside data and then inside methods i am added some code:
var self = this;
{
self.cacheDom.$submitItem.click(function () {
self.addItemArray.push({
‘id’: $(’#accountSearch’).data(‘id’).trim(),
‘name’: $(’#accountSearch’).val().trim(),
‘type’: $(’#accountDropdown option:selected’ ).text().trim()
});
$(’.addItemMenu’).hide();
});
}
i pushing the data into addItemArray. Then another one click function inside methods that time i need the addItemArray items. But i getting always a empty array.
Thanks

Watch all properties of a reactive data in Vue.js

I had an API call to the backend and based on the returned data, I set the reactive data dynamically:
let data = {
quantity: [],
tickets: []
}
api.default.fetch()
.then(function (tickets) {
data.tickets = tickets
tickets.forEach(ticket => {
data.quantity[ticket.id] = 0
})
})
Based on this flow, how can I set watcher for all reactive elements in quantity array dynamically as well?
You can create a computed property, where you can stringify the quantity array, and then set a watcher on this computed property. Code will look something like following:
computed: {
quantityString: function () {
return JSON.stringify(this.quantity)
}
}
watch: {
// whenever question changes, this function will run
quantityString: function (newQuantity) {
var newQuantity = JSON.parse(newQuantity)
//Your relevant code
}
}
Using the [] operator to change a value in an array won't let vue detect the change, use splice instead.