How to add dynamic array index value in angular html page - javascript

I am new to angular I want to add dynamic array index value in html page. I tried different solution I am not getting a solutions. I am not getting any error as well.
I have create a array in typescript as shown below
my typescript
months : string[] = ['January','February','March','April','May','June','July','August','September','October','November','December'];
the above array I want to pass dynamic index value in html page. I tried but I am not getting the value.
I tried like this {{ months[ result.startDate.split('/')[1] ] }} . If i type static index value it is working.
html page
<div class="row" style="width: 110%;" *ngFor="let result of allEvents">
<p class="start-date" >{{ result.startDate.split('/')[0] }} </p> <br><p >{{ months[ result.startDate.split('/')[1] ] }} </p>
</div>
result object I am getting
0:
_id: "5e8b033bd3d04a24db92288a"
name: "Casting call for kannada movie"
description: "Looking for:↵Female artist Age: 17-26↵Kids Age :4-12"
startTime: "6"
endTime: "21"
startDate: "04/04/2020"
endDate: "31/05/2020"
participant: []
userId: "5e536de00d691f6427bcaec1"
pageId: {profileImage: {…}, coverPage: {…}, isBlocked: false, softDelete: false, isVerified: true, …}
createdAt: "2020-04-06T10:23:55.874Z"
updatedAt: "2020-04-06T10:23:55.874Z"
please help me
thanks in advance

That why it is not working. You need to remove 0 from 04 before putting value in the month array.
Parse your index with parseInt before passing it in the month array.
Please see the example below. It is in core JS.
Let me know, If you want it in an angular format I will create a stackblitz example for you
var months = ['January','February','March','April','May','June','July','August','September','October','November','December'];
var result = {};
result.startDate = "04/04/2020";
var key = parseInt(result.startDate.split('/')[1]);
console.log(months[key]);
Please check this link for an example in angular - Example

Try like this:
.html
<p class="start-date" > </p> <br><p>{{getMonthName(result.startDate) }} </p>
.ts
getMonthName(month) {
return this.months[(parseInt(month.split("/")[1])-1)];
}
Working Demo

component.html
<div> {{getMonthName(result.startDate) }} </div>
component.ts
getMonthName(date) {
return this.months[(new Date(date).getMonth())]
}

Another aproach is transfor your object so, startDate and endDate becomes Date
allEvents.forEach(x=>{
x.startDate=new Date(x.startDate)
x.endDate =new Date(x.endDate )
})
And use pipeDate
{{result.startDate| date:'MMM'}}

Related

Vue js data logic - booking table

I need to make a table of bookings (the hours are the y, the slots (actually tennis courts) the x).
I will populate an array from my database with the already occupied
slots (court 5 at 5PM,...);
I'll then loop trough all possibilities (from 7AM to 12PM and for
each hour, every slots) and put the booking's name when taken, and
put a button when it's not.
I can't figure out how to structurate my data;
In Php I had an array like $bookings[$hour][$court] which, when not empty, should contain the booking name (in the php nested loops (hours and courts), I checked if $bookings[$hour][$court] was empty (and then display the content if any or a button otherwise).
I hope I'm clear enough...
Thank you all !
EDIT:
I tried that way:
new Vue({
el: '#app',
data: {
bookings: [
{
hour: '1',
court: '3',
name: 'Laurent'
},
{
hour: '2',
court: '2',
name: 'Gaspard'
}
]
}
})
And
<script src="https://unpkg.com/vue"></script>
<div id="app">
<table>
<tr v-for="hour in (7, 24)" :key="hour">
<td v-for="court in (1,6)" :key="court">
<div v-if="">
</div>
</td>
</tr>
</table>
</div>
But I don't kow how to link the data to the template...
You could create a method that filters the bookings by the court and hour indexes in your loop.
methods: {
getBookings( hour, court ) {
return this.bookings.filter( booking => booking.hour == hour && booking.court == court );
},
},
This returns an array of appointments so I'd use v-for instead of v-if. This means less code in the js, you don't have special code to handle the case where the returned array is empty, and your code will show if you have double bookings.
<div v-for="booking in getBookings( hour, court )" >
{{ booking.name }}
</div>

Can I make an attribute appear only once in a vue v-for

I have an array of people with associated teams. I want to display all the people in the record, but I only want to display their team name once.
Meaning, if the v-for loop has encountered this particular team name, it should put it in a new temporary array to signify that it should be unique, then when it encounters that team name again, checks it through that temporary array and prevent it from showing again.
Sample HTML Code:
<div id="a-list">
<div v-for="person in people">{{person.Name}}, {{person.Team}}</div>
</div>
Sample Vue Code:
var crew = new Vue({
el: "#a-list",
data: {
people:
[ { "Name": "Richard","Team":"DMS"}, { "Name": "Mark","Team":"VV"}, { "Name": "Steve","Team":"VV"}, {"Name":"Koji","Team":"MZ"}, {"Name":"Jamie","Team":"VV"} ]
}
});
Expected Output:
Richard, DMS
Mark, VV
Steve,
Koji, MZ
Jaimie,
Is this possible to do directly from the v-for loop and not in the JS file?
Edited to show more data that are not sequential
Update: As Fabio has pointed out, the above scenario wouldn't make much sense unless the order of the team is arranged sequentially in the output first. So his answer is correct.
This could be a solution:
<div id="a-list">
<div v-for="(person,index) in people"> {{person.Name}}, {{ ((index == 0) || person.Team != people[index-1].Team) ? person.Team : '' }}</div>
</div>

How Can I use Javascript to loop through an array and change and add extra HTML that outputs some text with those values?

For Example, I am using an API that returns an JSON array of values and I want to output them to the page.
Here is the full code I am working with if anyone wants to try it out to see where I can get it to work.
I have created Some HTML for the layout of the values I want to output when a button is clicked like so:
<p class="txData">
<p id="txHash">Transaction ID: </p><br>
<p id="txTime">Time: </p><br>
<p id="txToken">Token Symbol: </p><br>
<p id="txTo">To: </p><br>
<p id="txFrom">From: </p><br>
<p id="txValue">Amount Transferred: </p><br>
<p>***********************************</p><br>
</p>
I then assign variables for those elements which I want to append to:
let txHash = document.querySelector('#txHash');
let txTime = document.querySelector('#txTime');
let txToken = document.querySelector('#txToken');
let txTo = document.querySelector('#txTo');
let txFrom = document.querySelector('#txFrom');
let txValue = document.querySelector('#txValue');
And I append the retrieved values from the API by doing:
txHash.insertAdjacentHTML('beforeend', jsonFile.result[0].hash);
txTime.insertAdjacentHTML('beforeend', jsonFile.result[0].timeStamp);
txToken.insertAdjacentText('beforeend', jsonFile.result[0].tokenSymbol)
txTo.insertAdjacentHTML('beforeend', jsonFile.result[0].to);
txFrom.insertAdjacentHTML('beforeend', jsonFile.result[0].from);
txValue.insertAdjacentHTML('beforeend', web3.utils.fromWei(jsonFile.result[0].value, 'ether'));
This works to output the values wanted for the first Transaction (index [0]).
How could I create a loop that would basically use the template HTML at the start but then output it for the next 5 elements in the array so that it would be the details for each new trasanction outputted in the same format, but without having to code it 5 times?
I'm new to HTML and Javascript so appreciate any help. Thank you.
First piece of advice, if you don't already know it, you should avoid using static id's in your html template if you plan to use it for displaying a list, because id's must be unique in a single html page.
Second one, you should use a framework to help you displaying your data as a list. If you know famous ones such as Angular or React. You can also use jQuery as someone has advised you.
Here is a little example with VueJS which allows you to define components with html templates. Then, you can use them in a loop with the for directive (please note I'm not a VueJS expert and you may find better solutions) :
<body>
<div id="app">
<div v-for="json in jsonFile">
<data-display v-bind:json="json"></data-display>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
var DataDisplay = {
props: ['json'],
template: '<div class="txData">\
<p>Transaction ID: {{json.hash}}</p>\
<p id="txTime">Time: {{json.timeStamp}}</p>\
<p id="txToken">Token Symbol: {{json.tokenSymbol}}</p>\
<p id="txTo">To: {{json.to}}</p>\
<p id="txFrom">From: {{json.from}}</p>\
<p id="txValue">Amount Transferred: {{json.value}}</p>\
<p>***********************************</p>\
</div>'
};
var vm = new Vue({
el: "#app",
data: {
jsonFile: [
{
hash: 'hash1',
timeStamp: 'timestamp1',
tokenSymbol: 'token1',
to: 'to1',
from: 'from1',
value: 'value1'
}, {
hash: 'hash2',
timeStamp: 'timestamp2',
tokenSymbol: 'token2',
to: 'to2',
from: 'from2',
value: 'value2'
}
]
},
components: {
'data-display': DataDisplay
}
});
</script>
</body>
Documentation used for the example :
https://v2.vuejs.org/v2/guide/components.html
https://v2.vuejs.org/v2/guide/list.html

Simple NG-IF filter not working with date but works with other data

So I have simple ng-repeat with an ng-if filter that does not seem to work for DATE but works for everything else (like cal, time). I don't know what I am doing wrong.
Controller:
$scope.twoWeeksForward=new Date();
$scope.twoWeeksForward.setDate($scope.twoWeeksForward.getDate() - 14);
$scope.sampledata = [
{ title: 'First Workout', time:1500 ,cal: 376, date: "2016-05-22T07:57:24.792Z"},
{ title: 'Second Workout', time:1100 ,cal: 20, date: 2016-05-22},
{ title: 'Third Workout', time:500 ,cal: 190, date: 01232016 },
{ title: 'Fourth Workout', time:4500 ,cal: 900, date: 01222016 }
];
HTML: (THIS PART DOES NOT WORK)
<div ng-repeat="items in sampledata" ng-if="{{items.date}}>{{twoWeeksForward}}">
I tested out some different syntax for the date field but nothing is working. Any help would be greatly appreciated:)
You don't use {{}} interpolation in ng-if ... it evaluates expressions directly. You are also missing a " to close the attribute value
Try
<div ng-repeat="items in sampledata" ng-if="items.date">
I think you would be better using a custom filter function on your ng-repeat, rather than a second directive (ngIf) on the same element:
View:
<div ng-repeat="items in sampledata | filter:isNextTwoWeeks">
Controller:
$scope.isNextTwoWeeks = function(item) {
return item.date && item.date > $scope.twoWeeksForward;
}
Note that the date comparison could do with some improvement and I'm not exactly sure of the logic you're trying to achieve so I just copied what you listed in your example.
Here is the correct format for ng-if.
<div ng-repeat="date in sampledata" ng-if="{{toDate(date.date)< twoWeeksForward}}">
You need to convert the date in the scope variable to date format as currently it is not in it so follow this
and add toDate function in controller
$scope.toDate = function(date) {
return new Date(date);
}

Filtering results in real time with AngularJS and MomentJS

I have an ng-repeat listing results but I'm aiming to only display elements containing today's date.
My current setup can do it, but needs a page reload to redefine the time variable and thus filter the results.
To be honest I'm not sure that such real-time filter (when is 00.00 the list becomes empty automatically) can be accomplished, so I'd be very grateful if you could shed some light into the issue.
Here's my current layout:
<div class="row msf-row"
ng-repeat="record in recordlist | filter: search | filter: record.date = dateJson "
ng-class="{ 'msf-cancelled': record.cancelled}">
<div class="col-md-1">{{record.date}}</div>
<div class="col-md-1"><strong>{{record.car}}</strong></div>
<div class="col-md-2">{{record.driver}}</div>
<div class="col-md-2">{{record.from}}</div>
</div>
And the relevant JS:
$scope.dateJson = moment().format("YYYY MM DD");
$scope.addRecord = function () {
$scope.recordlist.push(
{
date: $scope.dateJson,
car: $scope.carList.code,
driver: $scope.driverList.name,
from: $scope.locationList.place,
destination: $scope.locationList2.place,
pax: $scope.paxList
}
);
jsonToRecordLocalStorage($scope.recordlist);
};
So basically, the filter compares the $scope.dateJson with the object property record.date and filters the results, but of course date.Json is only loaded on page reload, not on real time.
Any inputs?
You can define your own filter function like here http://davidjs.com/2014/02/how-to-call-any-function-as-a-filter-in-angularjs/
this filter function would look something like this
$scope.filterRecordsByDate = function(record) {
var date = moment();
//reset to midnight
date.set('hours', 0).set('minutes', 0).set('seconds', 0);
//you might need to reset to midnight also the property 'record.date'
return record.date == date;
}
Then in your HTML
ng-repeat="record in recordlist | filter: search | filter: filterRecordsByDate "

Categories