I'm trying to use the angular2-counto directive inside an *ngFor loop.
I know that I need a unique string in each instance. So
<div
counto
[step]="30"
[countTo]="myArr[0].Amount"
[countFrom]="0"
[duration]="2"
(countoChange)="counto_0 = $event"
(countoEnd)="onCountoEnd()">
{{counto_0 | number:'1.0-0'}}
</div>
<div
counto
[step]="30"
[countTo]="myArr[1].Amount"
[countFrom]="0"
[duration]="2"
(countoChange)="counto_1 = $event"
(countoEnd)="onCountoEnd()">
{{counto_1 | number:'1.0-0'}}
</div>
...
Should become
<div *ngFor="let item of myArr"
counto
[step]="30"
[countTo]="item.Amount"
[countFrom]="0"
[duration]="2"
(countoChange)="??? = $event"
(countoEnd)="onCountoEnd()">
{{??? | number:'1.0-0'}}
</div>
But what can I use in the ??? as a unique param for each iteration of the loop? The counto directive needs a string param (I think). Attempts to use *ngFor=let i item of myArr; let i = index; and then somehow use the index in the directive don't work.
<div *ngFor="let item of myArr; let i = index;"
counto
[step]="30"
[countTo]="item.Amount"
[countFrom]="0"
[duration]="2"
(countoChange)="i = $event"
(countoEnd)="onCountoEnd()">
{{i | number:'1.0-0'}}
</div>
Results in Uncaught Error: Cannot assign to a reference or variable!
You are trying to assign $event to the i variável.
Try something like:
newVar[i] = $event
Related
I create two global variables
such as var DiscountRef = {};var shareDetail = [];
when the user add the form I store all the values in DiscountRef variable such as
RefValue = {Mobile:9876543210,Quantity:3}
$scope.shareDetail = Object.Keys(RefValue);//I try Object.entries also
when I want to display the data in the table
{{shareDetail}}
<div ng-repeat="share in shareDetail">
{{share.Mobile}}
{{share.Quantity}}
</div>
Its displaying empty array
I also try this
<div ng-repeat="(key, value) in shareDetail">
{{key}} : {{value}}
</div>
It will get the result.how can I access particular key value pairs such as MobileNo:9876543210 & Quantity:3
$scope.value = {Mobile:9876543210,Quantity:3};
$scope.shareDetail = [];
Object.keys($scope.value).forEach(function(key, value)
{
$scope.shareDetail.push({"item_name": key, "value": $scope.value[key]});
});
Then you can do ng-repeat:
<div ng-repeat="(key, item) in shareDetail">
{{item.item_name}} : {{item.value}}
</div>
Thanks
I would like to increment a class property inside ngFor for each iteration by 1.Let me know if there is a way.Thanks in advance.
Component Class:
class AA
{
property:number = 0;
}
Template:
<div *ngFor = "let sample of samples">
//increment property here
</div>
You can use index
<div *ngFor = "let sample of samples;let i = index">
<span [class]="'opacity-'+(i+1)">value {{i+1}}</span>
<button (click)="property = (i+1)">Set Selected Item</button>
</div>
Selected Item : {{property}}
Just create a function in your class and call it into the ngfor bloc
class AA
{
property:number = 0;
function increment_property(): void{
this.property++;
}
}
<div *ngFor = "let sample of samples">
{{ increment_property() }}
</div>
I have an event form that where I get information put it in the localstorage (I cannot use an API) and I want to take the startdate and enddate out of localstorage, change them so they appear as dd-mm-yyyy (not yyyy-mm-ddT00:00:00.000Z) The issue is getting them out of the array and setting them. I have no idea where to begin....
Here is my JavaScript/jQuery:
.controller("Events", function($scope, $location) {
let URL = "https://morning-castle-91468.herokuapp.com/";
$scope.authToken = localStorage.getItem("authToken");
$scope.username = localStorage.getItem("username");
$scope.events = [];
let lastEvent = 0;
while (localStorage.getItem("event"+lastEvent)){
$scope.events.unshift(JSON.parse(localStorage.getItem("event"+lastEvent)));
lastEvent++;
}
JSON.parse(localStorage.getItem("event")) || [];
$scope.submitForm = function() {
if ($scope.eventForm.$valid) {
$scope.event.username = $scope.username;
localStorage.setItem("event"+lastEvent, JSON.stringify($scope.event));
}
};
})
And here is my HTML:
<div class="row eventcontent" ng-repeat="event in events">
<div class="col-xs-12 eventpost">
<div class="row-flex">
<div class="col-xs-8 ">
<h4>{{ event.title }}</h4>
</div>
<div class="col-xs-4 ">
<h4>{{ event.name }}</h4>
</div>
<div class="col-xs-12 ">
<td>{{ event.description }}</td>
<br />
<br />
<p>{{ event.address }} <br /> {{ event.country }}</p>
<br />
<p>{{ event.status }}</p>
</div>
<div class="col-xs-12 ">
<p>{{ event.startdate }} {{ event.enddate }}</p>
</div>
</div>
</div>
</div>
To get Data from localstroage which will be an JSON ArrayList then,
var retrievedData = JSON.parse(localStorage.getItem("event"+lastEvent));
var setDateFormat = $filter('date')(new Date((retrievedData[1].substr(6)), 'dd-mm-yyyy'));
I'm not used to Angular.
But anyway, it looks like you are creating an array events having all the previously stored event.
You use unshift which is adding each event at the beginning of the array. The result probably is like so (for 2 elements):
$scope.events:
[ // That is event1
{
name:someValue,
description:someValue,
address:someValue,
country:someValue,
status:someValue,
startdate:"yyyy-mm-ddT00:00:00.000Z",
enddate:"yyyy-mm-ddT00:00:00.000Z"
},
// That is event0
{
//Same structure as above...
}
]
So now,, assuming you wish to have the last event, which is the first element in the events array, and the structure is as above, I would try:
// Retreive the dates from the first array element... Only the part before the "T" in each string.
var retreived_start = $scope.events[0].startdate.split("T")[0];
var retreived_end = $scope.events[0].enddate.split("T")[0];
// Split the date by the "-" to re-order...
var start_parts = retreived_start.split("-");
var end_parts = retreived_start.split("-");
// YYYY-MM-DD results
var formatted_start = start_parts[2] +"-"+ start_parts[1] +"-"+ start_parts[0];
var formatted_end = end_parts[2] +"-"+ end_parts[1] +"-"+ end_parts[0];
// Place it in your Angular controller array (? -- I'm unsure here)
$scope.event.startdate = formatted_start;
$scope.event.enddate = formatted_end;
But now that you've modified the event array... It may be stored as "formatted"... So be aware of that!
That line is doing absolutely nothing: JSON.parse(localStorage.getItem("event")) || [];, since not assigned to a variable, you can safely remove it.
In a previous question here, I am trying to show a date only when it has changed between 2 messages.
The difference is that I am now connected to a realtime database (Firebase), so I subscribe to the data source and pass it through the async pipe before going through index and *ngIf:
<div *ngFor='let message of (chat | async) ; let i = index'>
<button *ngIf="i == 0 || (message.timestamp | date: 'ddMMMMyyyy') != ((chat | async)[i-1].timestamp | date: 'ddMMMMyyyy')">
{{ message.timestamp | date:'ddMMM' }}
</button>
...
<!--More html elements below (omitted)-->
...
</div>
This works well when I first load the view, however, if I push a new entry into chat, I get the following error:
TypeError: Cannot read property '0' of null
Maybe I am not too sure how the async pipe works, but when I try returning {{ (chat | async).length }}, it works as intended. Any suggestions on a workaround/proper practice?
In case someone else finds this since it's the first result with the key words, I was able to get the index of a *ngFor with the async pipe like this (assuming messages is an Observable of an iterable):
<div *ngFor="let message of (messages | async); let i = index;">
Still not sure how the AsyncPipe can be manipulated here, but I did mange to find a workaround that involves not using the pipe. I will await a better answer hopefully before marking this closed.
I subscribe to the data source in my class, and manipulate the array with a for loop before displaying it.
The (template) code in my question has now become:
<div *ngFor='let message of messages; let i = index'>
<button *ngIf="message.isNewDay">
{{ message.timestamp | date:'ddMMM' }}
</button>
...
<!--More html elements below (omitted)-->
...
</div>
And in the controller:
private chatid: string //chat id passed from previous screen
private chat: FirebaseListObservable<any>;
private messages: any = [];
constructor(private firebase: FirebaseService,
private _datepipe: DatePipe) {
}
ionViewLoaded() {
this.chat = this.firebase.database.list('/chat-messages/' + this.chatid);
this.chat.subscribe((data) => {
this.messages = data;
for (let i: number = 0; i < this.messages.length; i++) {
if (i === 0)
this.messages[i].isNewDay = true;
else {
let date1 = this._datepipe.transform(this.messages[i].timestamp, 'ddMMMMyyyy');
let date2 = this._datepipe.transform(this.messages[i-1].timestamp, 'ddMMMMyyyy');
if (date1 !== date2)
this.messages[i].isNewDay = true;
else
this.messages[i].isNewDay = false;
}
}
});
}
Note that I am currently using DatePipe in the class code (as well as in the template), so it is necessary to use providers: [DatePipe] along with pipes: [DatePipe].
If you want to use *ngFor, AsyncPipe, and index together - you should use this construction:
<ul>
<li *ngFor="let person of obsPersons | async as persons; index as i">
{{i + 1}} out of {{persons.length}}: {{person.personId}}
</li>
</ul>
Tested and works on Angular 7.
As mentioned above by #Primal Zed let company of (filteredCompaniesAliases | async); let i = index" should do the trick, syntax sample with plain html table:
<table>
<tr *ngFor="let company of (filteredCompaniesAliases | async); let i = index"">
<td>
{{selectedDiscountableCharge.name}}
</td>
<td>
${{selectedDiscountableCharge.amount}}
</td>
<td>
${{selectedDiscountableCharge.amount - ( (selectedDiscountableChargePercentanges / 100) * selectedDiscountableCharge.amount ) }}
</td>
</tr>
</table>
in your component:
companyAliasFilterCtrl: FormControl;
filteredCompaniesAliases: Observable<any[]>;
...
this.filteredCompaniesAliases = this.companyAliasFilterCtrl.valueChanges
.pipe(
startWith(''),
map(company => company ? this.filterOperatorsAliases(company) : this.companies.slice())
);
I use a function for showing (or not) the date. So to show the date (in this example) only when it changes:
<ion-list no-lines>
<ion-item-sliding *ngFor="let trip of tripsExt$ | async; let i = index">
<ion-item>
<ion-row (click)="change(trip)">
<ion-col col-6>
{{showOnChange(trip.date)}}
</ion-col>
<ion-col col-6>
{{trip.end_address_name}}
</ion-col>
</ion-row>
</ion-item>
<ion-item-options side="left">
<button ion-button color="primary" (click)="delete(trip)">
Delete
</button>
</ion-item-options>
</ion-item-sliding>
</ion-list>
With showOnChange:
showOnChange(currentDate) {
if (currentDate != this.previousDate) {
this.previousDate = currentDate
return currentDate
}
return ''
}
I have this code. $scope.counter = '1';
<div ng-repeat="cat in catadata">
<div ng-if="cat.TopCategoryID = 2" >
<div ng-if="counter = 1" >
<div class="feedsDisplay" ng-init="counter = counter + 1">
Creater Img:{{cat.CreatedBy_Profile.Picture.URI}}"
</div>
</div>
</div>
</div>
I want to stop loop when counter = 2, I want to display just 1 result.
ng-init="counter = counter + 1
{{counter}}
displaying 11111 it should display 12345
you are comparing with = instead of ==
Try like this
ng-if="counter == 1"
value of counter is string . add + sign before counter
try like this
ng-init="counter = +counter + 1"
You cant stop ng-repeat conditionally.
To print only one result you can use
<div ng-repeat="cat in catadata | limitTo : 1">
OR
<div>{{catadata[0]}}</div>
Rather than misusing ng-repeat, ng-init and ng-if like this, just try to extract the first matching cat before you render it, e.g. in a controller, directive or service:
for (var i = 0, maxI = catadata.length; i < maxI; ++i) {
if (cat.TopCategoryID === 2) {
$scope.firstMatchingCat = cat;
break;
}
}
And then in the template:
<div class="feedsDisplay">
Creater Img:{{firstMatchingCat.CreatedBy_Profile.Picture.URI}}"
</div>