Iteration over handlebar helper - iteration

Is it possible to iterate over at handlebar helper which return an array of objects?
this is what the helper returns:
[Object, Object, Object, Object, Object]
there is 5 objects in the array and each has 2 keys a "year" and a "value".
The helper looks like this: {{getPeriodYears 'test' 'some Other Text'}}
I have tried this:
{{#getPeriodYears 'text' 'some Other Text'}}
<div>{{year}}</div>
<div>{{value}}</div>
{{/getPeriodYears}}
Which just prints this on top of the page: [object Object],[object Object],[object Object],[object Object],[object Object]

Related

Object.values - Remove unnessary properties or extract arrays from Datatables callback object

I am generating from Datatables data object by form_data = this.api().rows().data(); and i got
form_data array of array from Datatables (image in link)
If i convert this by console.log(Object.values(form_data)); i got this
Object.values for form_data (image in link)
Is some way how remove this other properties (functions etc) inside of object and will there only arrays and this should be convert by Object.values() or should somehow extract this arrays of form_data to new array variable where will only this arrays without other properties which are inside array ???
As #andrewjames proposed... i need to add .toArray() inside my callback function in Datatables
drawCallback: function() {
form_data = this.api().rows().data().toArray();
}
after this, Datatables generate me clean Object
see image Object from Datatables only with arrays

VueJS: :class, condition with index

I'm creating a list of (thumbnail) 2 images, and #click each image should be expanded to max-width, by adding said class ('max-w-full') to the classes. The class is added by setting the array entry with the same index nr. as the image (imgclicked[0], imgclicked[1]) in the list to 1.
data:() {
imgclicked=[0,0], //by default both are set to 'small'/not 'max-w-full'
},
the template part looks like this:
<template v-for="(image,index) in images>
<a #click="zoomImgClicked(index)">
<img :src="image.filename" :class={'max-w-full' : imgclicked[index]==1,'w-12' : imgclicked[index]==0}">
</a> // using this.imgclicked[index] gives me the error 'this.imgclicked[0] is undefined'
</template>
on click the method zoomImgClicked() ist launched:
zoomImgClicked: function(i){
if(this.imgclicked[i]==0){
this.imgclicked[i]=1
}else{
this.imgclicked[i]=0
}
},
But this is not working. If I open the vue console and change the values of imgclicked[0] manually from 0 to 1 it works (images ae being resized). Also I see the method doing it's work, when logging in the console, the values are changed from 0 to 1 and vice versa. But it's not reflected on the page #click.
Why is that?
Please read Change Detection Caveats in the Vue docs.
Vue cannot detect the following changes to an array:
When you directly set an item with the index, e.g. vm.items[indexOfItem] = newValue
When you modify the length of the array, e.g. vm.items.length = newLength
You should use the $set method for this:
this.$set(this.imgclicked, i, 1)
try with array syntax:
<img
:src="image.filename"
:class="[
{
'max-w-full': imgclicked[index]==1,
'w-12': imgclicked[index]==0
},
'static class if need'
]"
>

Vue : Updating deep dosn't trigger re-rendering

Im having an array that looks something like this:
customers : [ {customer : 'foo', address : {postalCode : 6655, city : 'somewhere'}}, ..
]
I render a list something like this :
<template v-for="(cust, inx) in customers">
<div>{{ customers[inx].customer }}</div>
<div>{{customers[inx].address.postalCode }}|{{ customers[inx].address.city}}</div>
</template>
Now I have a function that gets the city when people enters a new postalcode it fetches a city and sets it with :
this.$set(self.customers[inx].address, 'city', 'NewCityName');
The thing is, I can confirm that the text is actually changed in the correct object, but it doesnt trigger a re-rendering.
Am I using the $set function in a wrong way in this case?
It could be that this.customers is not set correctly (is not marked as oservable) i.e. not declared in data like {customers:[]}, or any of its items are not set correctly. If you evaluate in devtools console, it must give out for this.customer and any of its items something like: {__ob__: Observer} and in expanded view must contain an item __ob__: Observer {value: {…}, dep: Dep, vmCount: 0}. These types of errors are most annoying in vue.
Object and array elements are observed only if they exist. Array methods like push, splice are observed too, so this.array[2] = obj will not work if array length < 2 but this.array.push(obj) works as expected. In other cases $set(...) is necessary to mark element as observable.

How do I pass an array of objects into a Jade template

I have a complex array of JSON objects and I want to send that to my jade template so that so can create a visualization on the page I am rendering, but I keep having an issue with how the object is formatted.
In my controller I'm passing it like this
res.render('scatter', {
title: 'Scatter',
company: company,
graphdata: dataArray
});
in my view trying to display like this
script graphdata = "#{graphdata}";
When I log the result it looks like this
[object Object],[object Object]
when it should be an array of objects.
what am I doing wrong ?
The reason why it happens is that it tries to convert the Array into a String.
If you take an array of Objects and convert them to a string, you will get this.
(Go to browser console and do this [{a:4}, {k: 9}].toString(). And the result will be "[object Object],[object Object]".
If you want to display the array of Objects at it is, you can do:
"#{JSON.stringify(graphdata)}"

Iterating elements using NightWatchJS

How do i click a button returned by elements command in night watch
client.elements('xpath', ".//a[#class='abcd')]", function (allButtons){
console.log('Element value is '+element)
allButtons.value.forEach(function (element) {
this.elementIdClick(element, function(res){});
}
}
While running i am getting an error as
Element value is [object Object]
TypeError: Object #<Object> has no method 'elementIdClick'
So how do i get each element from the element list returned by client.elements
I realized the parameters for elementIdClick is wrong, i updated the code as
client.elements('xpath', ".//a[#class='abcd')]", function (allButtons){
allButtons.value.forEach(function (element) {
console.log('Element value is '+element)
this.elementIdClick(this.elementIdAttribute(allButtons.value[element].ELEMENT, 'id'), function(res){});
Now the error is
Element value is [object Object]
TypeError: Cannot read property 'ELEMENT' of undefined
So again back to original question. How do i get individual elements from a list of webelements using nightwatchJS
The following worked for me:
function iter(elems) {
elems.value.forEach(function(element) {
client.elementIdClick(element.ELEMENT)
})
};
client.elements('css selector', 'button.my-button.to-iterate', iter);
Each element is a JSON object of the form { ELEMENT: string } (so, has no method itself.)
this in forEach does not point to the element, nor client: you need to invoke client.elementIdClick() or will get a TypeError.
Hope it helps.
I used the following strategy to iterate over DOM elements using Nightwatch:
// Executing a function in the application context.
client.execute(function () {
// Get elements by CSS selector.
var elements = document.querySelectorAll('.elements');
// Iterate over them.
[].forEach.call(elements, function (element) {
// Manipulate each element.
element.click();
});
});
That snippet is inside a test of course.
If you use jQuery or something similar you can use that too.
I think the error is getting generated by your console.log() statement.
From the elements() command, allButtons.value will be an array of several objects. To access key pairs in that array, you need need to specify where in the array and then reference the object: allButtons.value[index].ELEMENT
Because you gave your .forEach() loop only one arg, it's interpreting that as the index for the array, and in my code sample below I replaced your local variable element with index for clarity. There is also no need to use the .elementIdAttribute() function; the number returned by allButtons.value[0].ELEMENT will work as the id.
client.elements('xpath', ".//a[#class='abcd')]", function (allButtons){
allButtons.value.forEach(function (index) {
console.log('Element value is '+index.ELEMENT)
client.elementIdClick(index.ELEMENT);}})
Hope that helps.