Change Vue.js array's elements to opposite with splice - arrays

<template>
<div>
<div
v-for="(a, i) in arr"
:key="i"
:checked="a"
#click="toggleItem(i)"
class="checkbox"
>
</div>
<div class="out">{{ arr }}</div>
</template>
<script>
export default {
data() {
return {
arr: [true, false, true, false, true, true, true],
};
},
methods: {
toggleItem(index) {
this.arr.splice(this.arr[index], 1, !this.arr[index]);
},
};
</script>
How can I change each element in the array arr from true to false and from false to true by clicking the checkbox button using splice method ?

You can use the splice() method to change each element in the array arr from true to false and vice versa by clicking the checkbox button. Here's an example of how you can do it:
methods: {
toggleItem(index) {
this.arr.splice(index, 1, !this.arr[index]);
},
};

Related

I can't access the props of my objects (Angular)?

I have this variable in my environment.ts:
featureToggle: {"feature1": true, "feature2: false}
In a service of mine, I want to give these values to a component with a getAll-method, just like:
getAll() {
return environment.featureToggle;
}
In a component I'm having an array and call the servicemethod in my ngOnInit, where I assign the values to my array. Through *ngFor im iterating through the array.
Then I get an ERROR NG0901 IterableDiffers.find.
Yes, it might be, because it is an Object Array, so I would have to convert it in my service first to a normal Array, or assign the values to an interface to work with it?
like
interface FeatureInterface {
feature: string,
isActive: boolean;
}
But I can't even .map through my environments variable nor does forEach work. I also tried Object.keys(environment.featureToggle). Is there any way to access and iterate my properties in my environment.ts and work with them in any component?
Component:
features: FeatureInterface[] = [];
ngOnInit(): void {
this.features = this.featureToggleService.getAllFeatures()
Html:
<div *ngFor="let item of features">
{{item.feature}}
...
Check this out!
let featureToggle = { "feature1": true, "feature2": false, "feature3": true};
const result = Object.entries(featureToggle).filter((e) => e[1]).map((i) => i[0]);
console.log(result);
UPDATE 1:
Based on the requirement(as mentioned in the comments), try this:
let featureToggle = { "feature1": true, "feature2": false, "feature3": true };
const result = Object.entries(featureToggle).map((i) => {
return {
feature: i[0],
isAvailable: i[1]
}
});
console.log(result);
[ { feature: 'feature1', isAvailable: true },
{ feature: 'feature2', isAvailable: false },
{ feature: 'feature3', isAvailable: true } ]

How to count elements in an array depending on value

I have an array of Answer Entities that has an structure that includes an array of Vthumbs.
Entities that can either have a boolean vthumbdown/vthumbup property.
And the problem is this: How can I count the number of elements in the Vthumbs array that have a true "vthumbdown" (and the number of elements that have false "vthumbup")?
{
"accepted": true,
"creationDate": "2018-12-21T15:42:34.497Z",
"id": 0,
"urlvanser": "string",
"userId": 0,
"vquestionId": 0,
"vthumbs": [
{
"creationDate": "2018-12-21T15:42:34.497Z",
"id": 0,
"userId": 0,
"vanswerId": 0,
"vquestionId": 0,
"vthumbdown": true,
"vthumbup": true
}
]
}
]
I can see the total number of items with {{vanswer.vthumbs.length}} but I can not think how to get the number of Ups and Downs
Here is a great reference on javascript arrays and their available methods on MDN. In this instance you would most likely want to utilize the filter method as follows.
vanswer.vthumbs.filter(vthumb => vthumb.vthumbdown).length;
vanswer.vthumbs.filter(vthumb => vthumb.vthumbup).length;
You can get this simply by filtering the array:
const ups = vanswer.vthumbs.filter(v => v.vthumbup).length;
const downs= vanswer.vthumbs.filter(v => v.vthumbdown).length;
Then use it in your template:
Ups: {{ ups }}
Downs: {{ downs }}
Edit: according to comments, you wanna count these things in the template. For that, you can build a simple pipe:
import { Pipe, PipeTransform } from '#angular/core';
#Pipe({
name: 'countThumbs'
})
export class CounterPipe implements PipeTransform {
transform(obj: any, upsOrDowns = 'ups'): any {
if (!obj.vthumbs || !Array.isArray(obj.vthumbs)) {
return null;
}
if (upsOrDowns === 'ups') {
return obj.vthumbs.filter(item => item.vthumbup).length;
} else {
return obj.vthumbs.filter(item => item.vthumbdown).length
}
}
}
You then use it in the template like this:
Thumbups: {{ vanswer | countThumbs:'ups' }}
Thumbdowns: {{ vanswer | countThumbs:'downs' }}
Here's a more generic approach at Stackblitz.

ng-repeat orderBy not working with Boolean? [duplicate]

I'd like to be able to sort by whether a variable is true or false.
Let's say we have a variable like so:
groups = {
{ name: 'first', value: true },
{ name: 'second', value: false },
{ name: 'third', value: true },
{ name: 'fourth', value: false }
}
And we can loop through it like so:
<div ng-repeat="group in groups">
{{group.name}} {{group.value}}
</div>
Which will give you the following:
first true
second false
third true
fourth false
But if I wanted to sort by a boolean value then I could do this:
<div ng-repeat="group in groups | filter:{value:true}">
{{group.name}} {{group.value}}
</div>
<div ng-repeat="group in groups | filter:{value:false}">
{{group.name}} {{group.value}}
</div>
Which would give me the following output (which I want):
first true
third true
second false
fourth false
Is there a way to do this using orderBy or filter in a single ng-repeat?
orderBy accepts and sorts by booleans.
Order the repeated element by the the 'value' property of 'group':
ng-repeat="group in groups | orderBy: 'value'"
This will reverse the order:
ng-repeat="group in groups | orderBy: '-value'"
If you would like to also sort by the 'name' property of 'group':
ng-repeat="group in groups | orderBy: ['value','name']"
use variable name instead obeject
orderBy:'Event':false
you will get the desired output like -
first true
third true
second false
fourth false

Object Array in AngularJS

I am newbie to AngularJS. I want array of objects name, selected and count like this at run-time :
$scope.filenames = [
{ name: 'abc', selected: false , count: 10},
{ name: 'ede', selected: false, count: 5},
{ name: 'xyz', selected: false, count: 2 },
{ name: 'pqe', selected: false, count: 8 }
];
So I have created restangular service that fetch the values of name, count and selected on runtime. The code to get runtime those values are :
//initialize the arrays
$scope.filenames=[];
$scope.filenames.count=[];
$scope.filenames.name=[];
$scope.filenames.selected=[];
//called rest service that fetch the names of all files
Restangular.one("getAllFiles").get().then(function(listAllFiles){
for(i=0;i<listAllFiles.length;i++){
var fileName=listAllFiles[i];
//then called another rest service that return the file name along with the count like abc=2
var parameter="getFileCount/fileName;
Restangular.one(parameter).get().then(function(countAndFileName){
var spilitFileCount=countAndFileName.split("myspiliter");
$scope.filenames.name.push(spilitFileCount[0]);
$scope.filenames.selected.push(false);
$scope.filenames.count.push(spilitFileCount[1]);
});
}
});
I am able to get count and file names successfully. I want all them to put in $scope.filenames array. So that I can use this array on my html page :
Html Code to display file name along with count is :
<div class="form-group" id="filename" style="display:none;">
<label class="col-sm-8 control-label" ng-repeat="filename in filenames">
<input
type="checkbox"
name="myName[]"
value="{{filenames.name}}"
ng-model="filenames.selected"
ng-click="toggleSelection(filename.name)"
> {{filename.name}} ({{filename.count}})
</label>
</div>
But I am unable to put the values into array $scope.filenames and use it at HTML view. If I am accessing the values of $scope.filenames outside of the outer rest service, then it has nothing at all. Where I am missing the things ?
Your code doesn't match at all with what you want. What you want is:
$scope.filenames = [
{ name: 'abc', selected: false, count: 10},
{ name: 'ede', selected: false, count: 5},
{ name: 'xyz', selected: false, count: 2},
{ name: 'pqe', selected: false, count: 8}
];
This is a single array, containing objects.
But your code does the following:
$scope.filenames = [];
$scope.filenames.count=[];
$scope.filenames.name=[];
$scope.filenames.selected=[];
This creates 4 arrays.
What you want is
$scope.filenames = [];
And you want to push objects with 3 properties in this array:
var spilitFileCount = countAndFileName.split("myspiliter");
var object = {
name: spilitFileCount[0],
selected: false,
count: spilitFileCount[1]
};
$scope.filenames.push(object);
Your ng-repeat body is wrong as well:
<label class="col-sm-8 control-label" ng-repeat="filename in filenames">
The above means: iterate over the array filenames; at each iteration, the current element is accessible using the variable filename.
So it should not be
value="{{filenames.name}}"
ng-model="filenames.selected"
but
value="{{filename.name}}"
ng-model="filename.selected"

NgRepeat filtering complex structure

I have been given a complex JSON object to display inside Angular and I'd like to filter it into two lists after having drilled down into the object.
The object structure is:
{
foo:
{
bar:
{
showA: { value: true, type: 'A' },
showB: { value: false, type: 'A' },
showC: { value: true, type: 'A' }
}
}
}
And I'm trying to achieve a list of "false" and "true".
In this case:
Disabled:
showB - Type: A
Enabled:
showA - Type: A
showC - Type: A
I can't filter the object and also can't obtain the "key" of the objects, e.g. "showA".
My attempt of using:
item in profile['foo']['bar'] | filter: { value: false }
Accesses the correct objects but I can't filter or get the "key" of it.
Here is a broken plunkr to demonstrate:
http://plnkr.co/edit/9NniQdo213AuEbf0pghA?p=preview
Any advice would be great!
Check out this working punkr: http://plnkr.co/edit/TdM9P592OXd6Bx81Bmbt?p=preview
It uses a custom filter, myFilter, which makes the filtering task pretty simple. myFilter returns a new object with only the objects having value equal to the value given as second argument to the filter.
app.filter('myFilter', function() {
return function(bar, value) {
var r = {};
for (var key in bar) {
if (bar[key].value == value) {
r[key] = bar[key];
}
}
return r;
}
});
To get the key with ng-repeat, use the following syntax:
<li ng-repeat="(key, item) in profile['foo']['bar'] | myFilter:false">
<input type="checkbox" ng-model="item.value" /> {{ key }}
</li>
If you can alter the structure of $scope.profile, the filtering task would be easier with this structure:
bar: [
{name: 'ShowA', value: false, type: 'A'},
...
]

Resources