How to convert datetime in seconds ANGULAR JS - angularjs

I am fetching data from JSON in my controller and need to convert it into seconds.
[
{
"Id": "0",
"Name": "Subscriber",
"ItemsCount": 5,
"ItemsFailedCount": 6,
"ExecutionStart": "2015-08-01T08:01:00.9748076+01:00",
"ExecutionEnd": "2015-08-01T08:01:00.9748076+01:00"
}
]
What I am trying to achieve is getting the difference between "ExecutionStart" and "ExecutionEnd" in seconds.
I have looked upon for the solution of this on internet and couldn't find any solution unfortunately. So I have nothing to show that I've tried.
Kindly help.

First create Date objects from the date strings:
var executionStart = new Date(data[0].ExecutionStart);
var executionEnd = new Date(data[0].ExecutionEnd);
Then subtract the dates and divide by 1000 because difference will be in milliseconds and there are 1000 milliseconds in a second.
var diffSeconds = (executionEnd - executionStart) / 1000;
JsFiddle

solution using date.parse();
var data = [
{
"Id": "0",
"Name": "Subscriber",
"ItemsCount": 5,
"ItemsFailedCount": 6,
"ExecutionStart": "2015-08-01T08:01:00.9748076+01:00",
"ExecutionEnd": "2015-08-01T08:01:10.9748076+01:00"
}
];
var executionStarts = Date.parse(data[0].ExecutionStart);
var executionEnds = Date.parse(data[0].ExecutionEnd);
var diffSeconds = (executionEnds - executionStarts)/1000;
alert(diffSeconds);

Related

Discord.js outputting an entire array but want to add an emoji to correspond with each object

I am writing Guild Wars 2 commands into my bot and I have a wallet command which looks up ID's against an endpoint to give each ID a name. What I would like to do is instead of just displaying the name, I would like to display an emoji of each thing. For example, karma symbol for karma, gem symbol for gems. Adding emojis is easy, I get that part, however I can't wrap my head around how to identify what each line in the output is going to be as it is different per account that is looked up.
Here is my code so far:
var newArray = [];
for (var i = 0; i < walletArray.length; i++) {
for (var x = 0; x < currencyArray.length; x++) {
if (walletArray[i].id === currencyArray[x].id) {
if (currencyArray[x].name === "Coin") {
var bronze = String(walletArray[i].value).slice(-2)
var silver = String(walletArray[i].value).slice(-4, -2)
var gold = String(walletArray[i].value).slice(0, -4)
}
newArray.push(`${currencyArray[x].name} - ${walletArray[i].value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}`)
}
}
}
The walletArray (or part of it) is:
[
{
"id": 1,
"value": 57636
},
{
"id": 2,
"value": 32969
},
{
"id": 3,
"value": 36
}
]
The currencyArray is:
{
"id": 1,
"name": "Coin",
"description": "The primary currency of Tyria. Spent at vendors throughout the world.",
"order": 101,
"icon": "https://render.guildwars2.com/file/98457F504BA2FAC8457F532C4B30EDC23929ACF9/619316.png"
},
{
"id": 2,
"name": "Karma",
"description": "Earned through various activities. Spent at vendors throughout the world.",
"order": 102,
"icon": "https://render.guildwars2.com/file/94953FA23D3E0D23559624015DFEA4CFAA07F0E5/155026.png"
},
{
"id": 3,
"name": "Laurel",
"description": "Earned through the Log-in Reward Chest. Spent in major cities. Used to purchase various rewards.",
"order": 104,
"icon": "https://render.guildwars2.com/file/A1BD345AD9192C3A585BE2F6CB0617C5A797A1E2/619317.png"
}
The output is:
Wallet command output
I have no idea if I am even approaching this correctly but I just want it to look a bit nicer! It is fully functional just we can always improve things. My JS is not the best, it was learned during lockdown as something to do and was learned almost entirely from this website!
Any help would be appreciated, cheers.
Well, if I understand your problem correctly, you know each line of the output is gonna be, because of currencyArray.name. The solution should be something like:
var newArray = [];
for (var i = 0; i < walletArray.length; i++) {
for (var x = 0; x < currencyArray.length; x++) {
if (walletArray[i].id === currencyArray[x].id) {
var emote;
if (currencyArray[x].name === "Coin") {
emote = "🪙"
var bronze = String(walletArray[i].value).slice(-2)
var silver = String(walletArray[i].value).slice(-4, -2)
var gold = String(walletArray[i].value).slice(0, -4)
}
else if (currencyArray[x].name === "Karma") {
emote = "☯️"
}
else if (currencyArray[x].name === "Laurel") {
emote = "💳"
}
newArray.push(`${emote} ${currencyArray[x].name} - ${walletArray[i].value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}`)
}
}
}
Of course, use any emotes you wish.
Maybe you want to use a Map. discord.js names it Collection but they are pretty much the same.
let myMap = new Map();
myMap.set('key', 'emoji')
let emoji1 = myMap.get('key') //'emoji'
The 'key' is linked to the value which you can get with the Map.get method

Angular 6 compare two JSON Arrays

I am fetching notifications using API. Now here is the scenario:
1- I called the API, got 2 records and stored them in local variable (notifications) to show in view.
[{"id": 1, "notification": "bla"}, {"id": 2, "notification": "bla bla"}]
2- I am calling the same API to check for new notification after every 5 seconds. This time I need to compare the API response with the local variable, so if no new notification (different id) is in the record, don't push in local variable, other push.
I have tried something like this:
var val = JSON.parse(data);
if( val.length > 0 ) {
for( var i = 0; i < val.length; i++ ) {
this.notifications.forEach(element => {
if( element.id != val[i].id ) {
this.notifications.push(val[i]);
}
});
}
}
But its adding duplicate records. Any help would be appreciated.
Thanks
You need to use Array.find() to find the duplicate object in the val array.
var notifications = [{"id": 1, "notification": "bla"}, {"id": 2, "notification": "bla bla"}];
var data = `[{"id": 1, "notification": "bla"}, {"id": 4, "notification": "bla bla bla"}]`
var val = JSON.parse(data);
if( val.length > 0 ) {
val.forEach((obj)=>{
var existNotification = notifications.find(({id}) => obj.id === id);
if(!existNotification){
notifications.push(obj);
}
});
}
console.log(notifications);
Currently, you are getting duplicated element because the id value is compared against all the existing id values in notifications array. So, if one of the id do not match with another, it is pushed immediately into the notifications array. So, the better way and simple way is to use a find operation on the array to check the existing object.
A more robust way to handle this could be by using map in JS.
Rather than iterating the notifications (size = m) for every object in the data (size = n) would result in more time complexity of O(m x n).
Hence it could be done in O(n) as below:-
var notifications = new Map();
// assuming you get this at the beginning
var data1 = `[{"id": 1, "notification": "bla"}, {"id": 2, "notification": "bla bla"}]`;
checkAndAddNotification(data1);
// assuming you get this at the second time
var data2 = `[{"id": 1, "notification": "bla"}, {"id": 4, "notification": "bla bla bla"}]`
checkAndAddNotification(data2);
function checkAndAddNotification(data){
var val = JSON.parse(data);
if (val){
val.forEach((obj)=>{
var existNotification = notifications.get(obj.id);
if(!existNotification){
notifications.set(obj.id, obj);
}
});
}
}
console.log(notifications);
notifications.forEach((notification) => console.log(notification));
Please open the browser console as well while running the code.
Even if you plan to iterate over the map, the order would be preserved in the order the objects were inserted. Please look here for more.

Angular time formatting incorrectly

I am getting the following JSON back from a service:
{
"DailyEventCaseID": 1,
"LocID": "LA ",
"CourtRoom": "9",
"CaseID": 3,
"EventDate": "2015-09-14T00:00:00",
"SortTime": "08:30",
"SeqNumber": 1,
"StatusID": null,
"Case": {
"CaseID": 3,
"CaseNumber": "BP118652",
"DivisionCode": "PR",
"District": "LA ",
"CaseTitle": "KRAUS, MARGARITH - TRUST DTD 07/07/98"
},
"Status": null,
"Events": [
{
"EventID": 9,
"DailyEventCaseID": 1,
"EntityNumber": "0020",
"EventName": "INSTRUCTIONS",
"DailyEventCase": null
}
]
}
I want the field SortTime to display as 8:30 am so I have it in my view as:
{{case.SortTime | date: 'h:mm a'}}
It still just shows as 8:30 and not 8:30 am.
What am I doing wrong?
In your code, case.SortTime is not a date object. It is just a string. So date filter is not applied.
Method 1:
Assuming that you need only time regardless date, I suggest you this method. But it is not a good practice.
In your controller, you can overwrite case.SortTime as
timeParams = $scope.case.SortTime.split(':')
$scope.case.SortTime = new Date(0,0,0,timeParams[0],timeParams[1])
Now {{case.SortTime | date: 'h:mm a'}} will give you date with AM/PM.
See http://jsfiddle.net/radik305411/dys6atmj/ for help.
Method 2: Create a custom filter.
var app = angular.module('app', []);
app.filter('timeFilter', function () {
return function (sortTime) {
var timeParams = sortTime.split(":");
timeParams[2] = "AM"
if(timeParams[0] >= 12){
timeParams[0] -= 12;
timeParams[2] = "PM"
}
return timeParams[0]+':'+timeParams[1]+' '+timeParams[2]
};
});
Now {{case.SortTime | timeFilter }} will give the result you need.

How to push some data from Json into new array in AngularJS?

Let's say I have this Json ..
{
"name": "Mark",
"gender": "male",
"account1": {
"accountNo": 1201,
"balance": 300
},
"account2": {
"accountNo": 1354,
"balance": 5000
}
}
What I expect is like ..
$scope.myArray = [
{
"accountNo": 1201,
"balance": 300
},
{
"accountNo": 1354,
"balance": 5000
}
];
In AngularJS, how can I pick some part of Json data and push it into an array iteratively( I mean, when I have account1, account2 account3 or more, it can still add them into the array).
You could normally just assign the array over, but in this scenario that is not an option because your array is psuedo.
Ideally you would like to be able to do what this answer (related question) does: How to return and array inside a JSON object in Angular.js which is simply
$scope.myArray = json.accounts;
However, as noted, you do not have an accounts array so you need to make one.
var accounts = [];
for(var key in json){
if( !json.hasOwnProperty(key) // skip prototype extensions
|| !json[key].hasOwnProperty("accountNo") //skip non account objects
) continue;
accounts.push(json[key]);
}
And now you may use this array
$scope.myArray = accounts;
You can access Json data like an array. Like var foo = { ... , 'bar' = 'value', ... } you could get foo value by doing this for['bar']. So, by knowing this, you simply do something like
var arr = [];
for (var i = 0; i < 10; i++) {
arr.push(foo['account'+i]);
}
Although, this has nothing to do with angularjs.

Mongodb Mapreduce join array

I have a big collection of songs and want to get most played songs per week, in a array. as example:
{
"_id" : {
"title" : "demons savaites hitas",
"name" : "imagine dragons"
},
"value" : {
"weeks" : [
{
"played" : 56,
"week" : 9,
"year" : 2014
}
]
}
}
It sometimes becomes:
{
"_id" : {
"title" : "",
"name" : "top 15"
},
"value" : {
"played" : 1,
"week" : 8,
"year" : 2014
}
}
The collection which i get the data from is named songs and new fields get added all the time when a songs get added. No unique artistnames or songtitles and every document in the collection looks like this:
{
"_id" : ObjectId("530536e3d4ca1a783342f1c8"),
"week" : 8,
"artistname" : "City Shakerz",
"songtitle" : "Love Somebody (Summer 2012 Mix Edit)",
"year" : 2014,
"date" : ISODate("2014-02-19T22:57:39.926Z")
}
I now want to do a mapreduce which add the new week to the array. It now overwrites it.
I also noted when trying to change to a array, not all the played get counted, with the new mapreduce.
The new mapreduce not working, with weeks:
map = function () {
if (this.week == 9 && this.year == 2014) emit({title:this.songtitle.toLowerCase(), name:this.artistname.toLowerCase()}, {played:1, week:this.week, year:this.year});
}
reduce = function(k, values) {
var result = {};
result.weeks = new Array();
var object = {played:0, week: 0, year: 0};
values.forEach(function(value) {
object.played += value.played;
object.week = value.week;
object.year = value.year;
});
result.weeks.push(object);
return result;
}
db.songs.mapReduce(map,reduce,{out: {reduce:"played2"}})
This is the old one i'm using with is a new field in the collection per week and song:
map = function () {
if (this.week == 10 && this.year == 2014) emit({title:this.songtitle.toLowerCase(), name:this.artistname.toLowerCase(), week:this.week, year:this.year}, {count:1});
}
reduce = function(k, values) {
var result = {count: 0,};
values.forEach(function(value) {
result.count += value.count;
});
return result;
}
db.songs.mapReduce(map,reduce,{out: {merge:"played"}})
I get the information fro the toplist right now from played2 like this:
db.played2.find({'_id.week': 9,'_id.year': 2014}).sort(array("value.count" => -1)).limit(50)
Above line can include any typo because i use mongoclient for php and needed to change it to javascript syntax for you.
What am I doing wrong?
I found out that I could do mapreduce as the code snippet above and then just get this week in a query and another one for previous week and do simple double for with a if to update this week with previous week place.
I made the script in python, which i run also for my mapreduce as a cronjob. As example:
if len(sys.argv) > 1 and sys.argv[1] is not None:
week = int(sys.argv[1])
else:
week = (datetime.date.today().isocalendar()[1]) - 1
year = datetime.date.today().year
previous_week = week - 1
client = MongoClient()
db = client.db
played = db.played
print "Updating it for week: " + str(week)
previous = played.find({"_id.week": previous_week, "_id.year": year}).sort("value.count", -1).limit(50)
thisweek = played.find({"_id.week": week, "_id.year": year}).sort("value.count", -1).limit(50)
thisplace = 1
for f in thisweek:
previous.rewind() # Reset second_collection_records's iterator
place = 1
if previous.count() > 0:
checker = bool(1)
for s in previous:
if s["_id"]["name"] == f["_id"]["name"] and s["_id"]["title"] == f["_id"]["title"]:
result = played.update({"_id.week": f["_id"]["week"], "_id.year": f["_id"]["year"], "_id.title": f["_id"]["title"], "_id.name": f["_id"]["name"]}, {"$set": {"place.previous_week":place, "place.this_week":thisplace}})
checker = bool(0)
print result
place = place + 1
if checker is True:
result = played.update({"_id.week": f["_id"]["week"], "_id.year": f["_id"]["year"], "_id.title": f["_id"]["title"], "_id.name": f["_id"]["name"]}, {"$set": {"place.previous_week":0, "place.this_week":thisplace}})
print result
else:
result = played.update({"_id.week": f["_id"]["week"], "_id.year": f["_id"]["year"], "_id.title": f["_id"]["title"], "_id.name": f["_id"]["name"]}, {"$set": {"place.previous_week":0, "place.this_week":thisplace}})
print result
thisplace = thisplace + 1
print "done."
This seems to work very good. Hopefully mongodb adds support to just update a field or anything in mapreduce to add information to a document without overwrite it.
I'm taking a stab at the structure of your collection based on your input fields, but I don't think mapReduce is the tool you want. Your apparent desired output can be achieved using aggregate :
db.collection.aggregate([
// Match a specific week and year if you want - remove if you want all
{ "$match": { "year": inputYear, "week": inputWeek } },
// Group to get the total number of times played
{ "$group": {
"_id": {
"title": { "$toLower": "$songtitle" },
"name": { "$toLower": "$artistname" },
"week": "$week",
"year": "$year"
},
played: { "$sum": 1 }
}},
// Sort the results by the most played in the range
{ "$sort": { "year": -1, "week": -1, "played": -1 } },
// Optionally limit to the top 15 results
{ "$limit": 15 }
])
That basically is what you appear to be trying to do. So this sums up the "number of appearances" as the number of times played. Then we take the additional steps of sorting the results, and optionally (if you can live with looking for one week at a time) limits the results to a set number. Those last two steps you won't get with mapReduce.
If you are ultimately looking for the "top ten" for each week, as a single query result, then you can look at this for a discussion (and methods to achieve) what we call the "topN" results problem.

Resources