NaN showing even with number (angularjs) - angularjs

In the controller:
$scope.startCount = 0;
$scope.vs = function (number) {
$scope.startCount = number;
}
$scope.startTimeout = function () {
$scope.startCount = $scope.startCount + 1;
mytimeout = $timeout($scope.startTimeout, 1000);
}
$scope.startTimeout();
$scope.stopTimeout = function () {
$timeout.cancel(mytimeout);
alert("Timer Stopped");
}
$scope.meals = [
{ title: 'Abs', url:"#/app/mworkouts",id: 100, img: "img/female.jpg", vid:"vid/1.mp4",},
{ title: 'Arms', url:"#/app/browse",id: 2 , img: "img/male.jpg", vid:"vid/2.mp4"},
{ title: 'Biceps', url:"#/app/search",id: 3, img: "img/Spotify_2.jpg", vid:"vid/1.mp4" },
{ title: 'Legs', url:"#/app/search",id: 4, img: "img/Spotify_4.jpg", vid:"vid/2.mp4" },
{ title: 'Core', url:"#/app/mworkouts",id: 5, img: "img/female.jpg", vid:"vid/1.mp4" },
{ title: 'Back', url:"#/app/mworkouts",id: 6, img: "img/male.jpg", vid:"vid/2.mp4" }
];
In the html:
<div ng-repeat="m in meals">
<button ng-click='vs({{m.id}})'>Setter</button>
</div>
So how it is supposed to work is pass in a number from the array and then count up using $timeout. It works perfectly fine if I enter in a number manually but I want the number to come from the array. Also, {{m.id}} is definelty a number because I have tested it {{m.id-60}} and it works. I am have no idea what is wrong.
Sorry about the weird names...it's just an example :)

Just get rid of the {{}}
ng-click='vs(m.id)'

It's seems to work for me here! I added couple of log for you to make sure
<div ng-repeat="m in meals">
<button ng-click='vs(m.id)'>Setter</button>
</div>
http://plnkr.co/edit/tpl:rfqcl9AHEoJZEEJxyNn2?p=preview

Related

Array: How to change specific values dependent on index (Rating function)

I'm sorry for the terrible title, but somehow I can't explain it better in one sentence.
What I want to do is a rating component in my Vue App. So if I click the 3rd star, the two stars before that one are set to "true" as well.
What I got:
const ratingsArray = [
{
name: 'rating1',
ratingCount: 1,
isClicked: ref(false)
},
{
name: 'rating2',
ratingCount: 2,
isClicked: ref(false)
},
{
name: 'rating3',
ratingCount: 3,
isClicked: ref(false)
},
{
name: 'rating4',
ratingCount: 4,
isClicked: ref(false)
},
{
name: 'rating5',
ratingCount: 5,
isClicked: ref(false)
},
]
I just got a toggle function to toggle isClicked:
function toggleClick(x) {
x.value = !x.value
}
This is my template
<template>
<div v-for="rating in ratingsArray"
:key="rating.name"
#click="toggleClick(rating.isClicked)"
:class="[rating.isClicked.value ? 'ratingBoxFilled' : 'ratingBox']">
</div>
</template>
How can I say, that if rating3 is clicked (so isClicked is true), rating1 and rating2 also got to be true?
It seems that I need to work with the index in my array. But somehow, I cannot create an idea. Maybe you guys can help me out. Thank you!
A simple loop would do the trick:
<template>
<div v-for="(rating, index) in ratingsArray"
:key="rating.name"
#click="toggleClick(index)"
:class="[rating.isClicked.value ? 'ratingBoxFilled' : 'ratingBox']">
</div>
</template>
function toggleClick(ratingIndex) {
for (let i = 0; i < ratingsArray.length; i++) {
// Set ratingsArray[i].isClicked to true if it's within the requested range
ratingsArray[i].isClicked.value = (i <= ratingIndex);
}
}
You guys are great. I didn't thought of an for loop.
So here is my final solution:
<div
v-for="(rating, index) in ratingsArray"
:key="rating.name"
#click="updateRating(index, rating.ratingValue)"
:class="[rating.isEnabled.value ? 'ratingBoxChecked' : 'ratingBox']">
</div>
function updateRating(ratingIndex: number, ratingValue: number) {
for (let i = ratingIndex; i < 5; i++) {
ratingsArray[i].isEnabled.value = false;
}
for (let i = 0; i <= ratingIndex; i++) {
ratingsArray[i].isEnabled.value = true;
}
console.log('Rating Value: ' + ratingValue)
}
First I clean all the enabled dots.
Then it will run until the given index and set the boolean value to true. Thats all.

How to loop over nested array in vue and display data every 5 seconds?

I'm using Vue Js and I have a nested array like this:
arrays: [
{
name: 'Max',
Info: [60, 75, 70, 85, 65],
},
{
name: 'Dave,
Info: [70, 95, 60, 65, 83],
},
]
I have a user profile box that displays name and info for each user.
<div class="outer" v-for="(item, index) in arrays" :key="item.id" v-bind:id="item.name">
I would like to display info in template:
<div class="box c" >Info<span v-for="info in item.Info">{{info}}</span></div>
When I did this it showed the correct array for the correct user but it displayed all numbers
but I would like info to show each number only for 5 seconds until the last number. So for Max it will display 60 then wait 5 seconds, then will only show 75 wait 5 seconds etc until it stops at the last number and only displays that number.
I tried creating a function :
appendInfo: function() {
for (let i = 0, l = this.arrays.length; i < l; i++) {
let info = this.arrays[i]['Info'];
let timer = 0;
for (let i = 0; i < info.length; i++) {
setTimeout(() => this.rate = info[i], timer);
timer = timer + 5000;
}
}
and passed data to rate
return {
count: null,
rate: [],
and used {{rate}} in the template
<div class="box c" >Info<span>{{rate}}</span></div>
but it only displayed data from the second user profile for both profiles.
So I'm wondering if there is either a way to do this with v-for or how I can modify my function?
Thanks!
Update
I used the RateDisplayer component like so:
<div class="outer" v-for="(item, index) in arrays" :key="item.id" v-bind:id="item.name">
<rate-displayer :rates="item.Info" />
import RateDisplayer from './RateDisplayer'
export default {
name: 'card',
props: {
rates: {
required: true,
}
},
data () {
return {
interval: 5000,
rate: false,
...
but still displayed only last arrays values.
Fixed
I removed from parent component:
props: {
rates: {
required: true,
}
},
interval: 5000,
rate: false,
and now it's working, thanks again!
I did something like that before. First, I suggest you to create a component JUST for this part:
<div class="box c" >Info<span>{{rate}}</span></div>
then, in this component you can accept rates as prop, and set rate every 5 sec to the new one. Something like:
<template>
<div class="box c" v-if="rate">Info<span>{{rate}}</span></div>
</template>
export default {
name: "RateDisplayer.vue",
props: {
rates: {
required: true,
}
},
data() {
return {
interval: 5000,
rate: false
}
},
mounted(){ this.nextOrStop(-1) },
methods: {
nextOrStop(current)
{
if(current === this.rates.length-1) { return }
setTimeout( () => {
const index = current+1;
this.rate = this.rates[index];
this.nextOrStop(index)
}, this.interval)
}
....
You can insert this component inside your parent component like this:
<div class="outer"
v-for="(item, index) in arrays"
:key="item.id"
v-bind:id="item.name">
<rate-displayer :rates="item.Info" />
</div>

Angularjs select display value if not in array

I would like to create a select for add and remove value in my array. But the value must be unique.
This is my code but dosen't work correctly because I don't know how I can to hide or show the value in the select
<div ng-app="myApp">
<div ng-controller="myController">
<p>Select something</p>
<select ng-model="selectedBucket"
ng-options="row as row.display for row in bucketEnum | filter:bootstrapValues">
</select>
<button ng-click="add(selectedBucket.value)">
add
</button>
<br>
{{initialSet}}
<br>
{{bucketEnum}}
</div>
</div>
And controller and filters :
var app = angular.module('myApp', []);
app.controller('myController', function ($scope, $filter) {
$scope.initialSet = [1, 2, 4, 7];
$scope.bucketEnum = [
{ display: '0', value: 0, bool:true },
{ display: '1', value: 1, bool:true},
{ display: '2', value: 2, bool:true },
{ display: '3', value: 3, bool:true },
{ display: '4', value: 4, bool:true },
{ display: '5', value: 5, bool:true },
{ display: '6', value: 6, bool:true },
{ display: '7', value: 7, bool:true }
];
$scope.add = function(value){
$scope.initialSet.push(value);
$scope.selectedBucket = $filter('bootstrapValues')($scope.initialSet, $scope.bucketEnum);
}
});
app.filter('bootstrapValues', function(){
return function(initial, baseBucket){
var result = [];
for(var i = 0; i < initial.length; i++){
var flag = false;
for(var j=1; j<baseBucket.length; j++){ //from 1 or 0.. you call
if(initial[i] === baseBucket[j].value){
flag = true;
baseBucket[j].bool = false;
break; // if there are repeated elements
}
}
}
return result;
};
});
If you want to disable the added value in current select, then You can achieve this by disable when syntax of angular 1.4+ version
See this fiddle of your code.(for disable)
and, If you want to delete the added value in current select then See this fiddle (for delete)

Vue.js filtering on array

I am trying to filter an array using a computed property in vue.js. I would like to search on on multiple fields, name, state, tags etc.
My data:
events: [
{
id: 1,
name: 'Name of event',
url: '#',
datetime: '2017-05-10T00:00:00Z',
description: 'The full text of the event',
state: 'VIC',
tags: [
'ordinary',
'advanced'
]
},
{
id: 2,
name: 'Another event',
url: '#',
datetime: '2017-05-12T00:00:00Z',
description: 'The full text of the event',
state: 'VIC',
tags: [
'beginner'
]
},
{
id: 3,
name: 'Great event',
url: '#',
datetime: '2017-05-18T00:00:00Z',
description: 'The full text of the event',
state: 'NSW',
tags: [
'beginner'
]
}
]
},
The following function works as expected, however I cant work out how to have it search the items in 'tags' (commented out).
searchevents: function(){
let result = this.events
if (this.filterValue){
result = result.filter(event =>
event.name.toLowerCase().includes(this.filterValue.toLowerCase()) ||
event.state.toLowerCase().includes(this.filterValue.toLowerCase())
// event.tags.toLowerCase().values().includes(this.filterValue.toLowerCase())
)
}
return result
}
The following returns a blank array, this method works ok when i have done it in angular but not in vue.
searchevents2: function(){
var searchRegex = new RegExp(this.filterValue,'i')
this.events.filter(function(event){
return !self.filterValue || searchRegex.test(event.name) || searchRegex.test(event.state)
})
}
Ideally I would either like to be able to list array items to filter by or just filter by the entire array.
Appreciate any help, first post here so be gentle. I have a lot more experience with Python than Javascript so i may also use incorrect terminology at times.
You weren't too far off.
For your searchEvents filter, you just needed to add the tag filter. Here's how you might do that.
searchevents: function(){
let result = this.events
if (!this.filterValue)
return result
const filterValue = this.filterValue.toLowerCase()
const filter = event =>
event.name.toLowerCase().includes(filterValue) ||
event.state.toLowerCase().includes(filterValue) ||
event.tags.some(tag => tag.toLowerCase().includes(filterValue))
return result.filter(filter)
}
Array.some() is a standard array method that returns true if any element of the array passes your test.
searchevents2: function(){
const searchRegex = new RegExp(this.filterValue,'i')
return this.events.filter(event =>
!this.filterValue || searchRegex.test(event.name) || searchRegex.test(event.state))
}
With searchEvents2 you really only left an errant self in there. Either you needed to set self before you executed the filter, or, as I have done here, turned it into an arrow function.
Example.
const app = new Vue ({
el: '#app',
data: {
search: '',
userList: [
{
id: 1,
name: "Prem"
},
{
id: 1,
name: "Chandu"
},
{
id: 1,
name: "Shravya"
}
]
},
computed: {
filteredAndSorted(){
// function to compare names
function compare(a, b) {
if (a.name < b.name) return -1;
if (a.name > b.name) return 1;
return 0;
}
return this.userList.filter(user => {
return user.name.toLowerCase().includes(this.search.toLowerCase())
}).sort(compare)
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.js"></script>
<div id="app">
<div class="search-wrapper">
<input type="text" v-model="search" placeholder="Search title.."/>
<label>Search Users:</label>
</div>
<ul>
<li v-for="user in filteredAndSorted">{{user.name}}</li>
</ul>
</div>

How to use the value in ngRepeat as a dynamic way to access a scope?

I have a set of value that I would like to dynamically generate in my view. How can I go about doing it in the following way?
$scope.mainKeyMapping = [
{
name: 'category1',
otherThings: ''
},
{
name: 'category2',
otherThings: ''
},
{
name: 'category3',
otherThings: ''
},
{
name: 'category4',
otherThings: ''
},
{
name: 'category5',
otherThings: ''
}
];
$scope.category1 = {something....}
$scope.category2 = {something....}
$scope.category3 = {something....}
$scope.category4 = {something....}
$scope.category5 = {something....}
HTML
<div ng-repeat="cat in mainKeyMapping">
{{category1}} // outputs obj
{{cat.name}} // outputs string "category1" <----- how do I output the obj?
</div>
First, put your categories into a collection:
$scope.categories = {
category1: {something....},
category2: {something....}
};
Now simply access the right category in your html:
<div ng-repeat="cat in mainKeyMapping">
{{categories.category1}} // outputs obj
{{categories[cat.name]}} // outputs obj
</div>

Resources