Angular time formatting incorrectly - angularjs

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.

Related

Convert raw string to JSON format

Hi I just have a question on how can I convert this API response into json data. I tried using explode but the response seems like separated into array.
StatCode: 11
StatName: cancelled
OrderID: OP_AFIFAH_6889
Amount: 1.10
TranID: 143519171
Domain: test
BillingDate: 2019-11-26 16:58:49
BillingName: test
VrfKey: test
Channel: credit
Currency: MYR
ErrorCode: CC_000
ErrorDesc: Successful Payment :
Maybe something like this
{
"StatCode": 11,
"StatName": "cancelled",
"OrderID": "OP_AFIFAH_6889",
"Amount": 1.10,
"TranID": 143519171
etc..
}
Thanks
The best way is changing the API to return the JSON object. If you don't have access to the API, I wrote a simple javascript for you which can convert it to the JSON object:
function toJSON(input) {
const lines = input.split('\n')
const result = []
for (let i = 1; i < lines.length; i++) {
if (!lines[i])
continue;
const obj = {}
const currentline = lines[i].split(':')
obj[currentline[0]] = currentline[1]
result.push(obj)
}
return JSON.stringify(result)
}
console.log(toJSON(`StatName: cancelled
OrderID: OP_AFIFAH_6889
Amount: 1.10
TranID: 143519171
Domain: test
BillingDate: 2019-11-26 16:58:49
BillingName: test
VrfKey: test
Channel: credit
Currency: MYR
ErrorCode: CC_000
ErrorDesc: Successful Payment :`)
);
[
{
"StatName": "cancelled",
"OrderID": "OP_AFIFAH_6889",
"Amount": 1.10,
"TranID": 143519171,
"Domain": "test",
"BillingDate": "2019-11-26 16:58:49",
"BillingName": "test",
"VrfKey": "test",
"Channel": "credit",
"Currency": "MYR",
"ErrorCode": "CC_000",
"ErrorDesc": "Successful Payment"
}
]
Note: Amount and TranID values are both numbers ,if you want them to be a type of string kindly add double quotes to them.
Thanks

how to get the min and max value from json in angular js

i want to get the maximum and minimum value from a json in angular js
my json:
{
"data":[
{
"name": "ranjith",
"age": 22
},
{
"name": "rahul",
"age": 20
},
{
"name": "jinesh",
"age": 25
},
{
"name": "vishnu",
"age": 24
}
]
}
and my controller:-
var app = angular.module('myApp', ['']);
app.controller('myCtrl', function($scope, data) {
$scope.data = data.data;
$scope.min="";
$scope.max="";
};
});
i want to get the minimum and maximum value from the array and store it in the Variables min and max
You can simply use
$scope.min = Math.min.apply(Math,$scope.data.map(function(item){return item.age;}));
$scope.max = Math.max.apply(Math,$scope.data.map(function(item){return item.age;}));
To avoid using 3rd party lib
for (var index in $scope.data.data)
{
var item=$scope.data.data[index];
if($scope.min==0 && $scope.max==0){
// set first default element
$scope.min=item.age;
$scope.max=item.age;
}
else{
if($scope.min>item.age)
$scope.min=item.age;
else if($scope.max<item.age)
$scope.max=item.age;
}
}
You can use Underscore.js with angular and then in your controller,
var ageArr = _.pluck(data.data, 'age');
$scope.min= _.min(ageArr);
$scope.max= _.max(ageArr);
Plunker url http://run.plnkr.co/plunks/Mw531cqUIHVSorb5kOac/
1.Add Underscore dependency
2.Use the following:
//For Maximum Age:
_.max(data, function(itr){ return itr.age; });
/* O/p = {
"name": "jinesh",
"age": 25
}*/
//For Minimum Age:
_.min(data, function(itr){ return itr.age; });
/* O/p = {
"name": "rahul",
"age": 20
} */
If the intent is to display, you can directly arrive at min by this:
{{(data | orderBy:'age')[0].age}}

Two dimensions data, display no results

I'm a beginner with angularJs
I have json data on two dimensions :
[
{
"nom": "Name 1",
"subventions": [
{
"beneficiaire": "ben\u00e9f Phipippe C mars 2015",
"montant": "7<span class='space'><\/span>898,99",
"annee": 1,
"trimestre": 4,
"infoAdditionnelle": "<p>info mars - 2015<\/p>\r\n<div id=\"nested_deluminate_fullscreen_workaround\" style=\"background-color: rgba(0, 0, 0, 0);\">\u00a0<\/div>"
},
{
"beneficiaire": "cvbcvbn",
"projet": "<p>cvnnncbcnbcbn<\/p>",
"circonscription": "456sdxfvxc",
"montant": "131,00",
"annee": 3,
"trimestre": 2,
"infoAdditionnelle": "<p>test<\/p>"
}
]
},
{
"nom": "Name 2",
"subventions": [
{
"beneficiaire": "pierre m",
"montant": "1<span class='space'><\/span>000,00",
"annee": 3,
"trimestre": 1,
"infoAdditionnelle": "<p>avtil 2015-16<\/p>"}
]
},
{
"nom": "Name 3",
"subventions": [
{
"beneficiaire": "bene pierre p avril 2015-16",
"montant": "1<span class='space'><\/span>222,00",
"annee": 3,
"trimestre": 1,
"infoAdditionnelle": "<p>p avril 2015-16<\/p>"
}
]
}
]
As you can see, there is an array of persons containing the field "nom" and "subventions", "subventions is also an array
I have filters by the fields "annee" and "trimestre", and what i want to do is when there's not result to display, to display a "no results" message
To calculate the number of results, i use this function
$scope.filterArray = function(resultsPersonnes) {
var data = resultsPersonnes.filter(function(prop) {
return prop.subventions[0].annee == $scope.annee.id;
});
if ($scope.myFilter.trimestre > 0) {
return data.filter(function(prop) {
return prop.subventions[0].trimestre == $scope.myFilter.trimestre;
});
} else {
return data
}
}
It's doesn't work for all the cases, you can see an example here http://plnkr.co/edit/9TbO0Hl9LziUS2B6AsAr?p=preview
If you click on "Juillet - septembre" in "Trimestre, i got one result, but the "no results" message is displayed!!!
do you see the error ? please help!
Thanks a lot
As you already guessed in your comment, you were checking only the first row. The fix is to check all rows, for example like this, using Array.some (which returns true if at least one item in array returns true for the function given as parameter)
Edit: the filtering needs to be updated into a single filter
$scope.filterArray = function(resultsPersonnes) {
var data = resultsPersonnes.filter(function(prop) {
return prop.subventions.some(function (subvention) {
var anneeMatches = subvention.annee == $scope.annee.id;
var trimestreMatches = true;
if ($scope.myFilter.trimestre > 0) {
trimestreMatches = subvention.trimestre == $scope.myFilter.trimestre;
}
return anneeMatches && trimestreMatches;
});
});
return data;
};
See working plunker

Creating arrays out of objects in AngularJS

Given the following object:
Object {November 2014: Object}
November 2014: Object
Cars: Object
324: Object
duration: 1417132808000
total: "00:00:08"
trips: 1
369: Object
duration: 5668531247000
total: "00:00:47"
trips: 4
391: Object
duration: 9919930257000
total: "00:10:57"
trips: 7
396: Object
duration: 9919929791000
total: "00:03:11"
trips: 7
KE-22: Object
duration: 5668531269000
total: "00:01:09"
trips: 4
I need to be able to create arrays from data extracted from it.
Something like this:
Labels: (Key from Objects inside Cars)
[324, 369, 391, 396, KE-22]
Series: (Properties from each object inside Cars)
[Trips, Total]
Data: (Values from properties for each object inside Cars)
[
[1,4,7,7,4], // Array of trips for each car, in order.
["00:00:08", "00:00:47", "00:10:57", "00:03:11", "00:01:09"] // Array of total duration for each car, in order.
]
With this arrays I intend to populate a chart for each month.
The collection of objects has been created using the following code, probably is relevant to the question:
var dataByMonth = _.groupBy($scope.recordlist, function(record) {
return moment(record.date, 'DD-MM-YYYY').format('MMMM YYYY');
});
dataByMonth = _.mapValues(dataByMonth, function(month) {
var obj = {};
obj.Cars = _.groupBy(month, 'car');
obj.Drivers = _.groupBy(month, 'driver');
_.each(obj, function(groupsValue, groupKey) {
obj[groupKey] = _.mapValues(groupsValue, function(groupValue) {
return _.reduce(groupValue, function(sum, trip) {
sum['trips']++;
sum['duration']+= moment.utc(trip.duration, 'HH:mm:ss');
sum['total'] = moment.utc(sum.duration). format('HH:mm:ss')
return sum;
}, {trips: 0, duration: 0, total:0})
});
})
return obj;
});
$scope.statistics = dataByMonth;
console.log($scope.statistics);
Any tips on how to proceed?
_.chain(cars).pairs().map(function(p) {
var id = p[0];
return [id].concat(_.values(p[1])); // produces an array of [{id, duration, trips, total}]
}).reduce(function(acc, as) {
// we assume properties are sorted
return _.map(as, function(a, i) {
return acc[i] = (acc[i] || []).concat([a]);
});
}, []).value();
A problem with objects is that they cannot guarantee the order of their properties.
This means that before converting to arrays, you need to somehow decide on a predifined sequence algorithm. In the code below this is the alphanumeric order of the property names.
var objPart = obj["November 2014"]["Cars"];
var ret = _.chain(objPart).transform(function(total, n , key){
//In this first iteration we collect all possible series that may exist,
total.series =_.union(total.series, _.keys(n) );
//and all labels
total.labels.push(key);
}, {labels:[], series:[], data:[]} ).mapValues(function(val){
//sorting labels, series. Data do not yet exist
return _.sortBy(val);
}).value();
//based on the above orders generate a multi dimensional array for data.
ret = _.transform(ret.labels, function(total, lbl){
var arr = _.transform(ret.series, function(partialTotal, ser){
partialTotal.push(objPart[lbl][ser]);
}, []);
total.data.push(arr);
}, ret);
console.log("Labels:",ret.labels);
console.log("Series:",ret.series);
console.log("Data:",JSON.stringify(ret.data));
The above solution will work even for the data below:
var obj = {
"November 2014": {
"Cars": {
"339": {
"trips": 1,
"total": "00:00:08",
"duration": 1417132809000,
},
"324": {
"trips": 1,
"extraProp1":"x",
"total": "00:00:08",
"duration": 1417132808000,
},
"369": {
"duration": 5668531247000,
"trips": 4,
"total": "00:00:47",
"extraProp2":"y"
},
"391": {
"duration": 9919930257000,
"trips": 7,
"total": "00:10:57"
},
"396": {
"duration": 9919929791000,
"total": "00:03:11",
"trips": 7
},
"KE-22": {
"duration": 5668531269000,
"total": "00:01:09",
"trips": 4
}
}
}
}
Output:
Labels: ["324", "339", "369", "391", "396", "KE-22"]
Series: ["duration", "extraProp1", "extraProp2", "total", "trips"]
Data: [[1417132808000,"x",null,"00:00:08",1],
[1417132808000,null,null,"00:00:08",1],
[5668531247000,null,"y","00:00:47",4],
[9919930257000,null,null,"00:10:57",7],
[9919929791000,null,null,"00:03:11",7],
[5668531269000,null,null,"00:01:09",4]]

Return an array from an Ember computed property

I have two related models - Task and Requirement. Requirements can be one of 3 types (Part, Tool, Material). A Task can have several requirements including several of the same type.
Task A
Requirement 1 (Part)
Requirement 2 (Part)
Requirement 3 (Tool)
Requirement 4 (Material)
Requirement 5 (Tool)
When viewing a single Task I want to group the list of requirements by type in a sort of summary view.
Task A
Parts Requirements (2)
Tooling Requirements (2)
Materials Requirements (1)
I have a computedProperty mostly functioning in my TaskController but I can't seem to get it to return back the array of requirement summaries that I'm building. All the fixture data is setup properly for both models (I can iterate each requirement and show it in the template with no issues).
Here are the models
Task model
App.Task = DS.Model.extend({
name: DS.attr()
requirements: DS.hasMany('requirement', { async: true})
});
Requirement model
App.Requirement = DS.Model.extend({
task_id: DS.belongsTo('task'),
type: DS.attr(),
description: DS.attr(),
quantity: DS.attr()
})
Here is the controller:
App.TaskController
App.TaskController = Em.ObjectController.extend({
requirementSummary: function () {
var self = this,
results = [];
self.get('requirements').then(function(requirements) {
var arrRequirements = requirements.get('content');
var parts = {
name: 'Parts',
description: '',
count: 0,
css_class: 'fa-cog'
},
tools = {
name: 'Tools',
description: '',
count: 0,
css_class: 'fa-wrench'
},
materials = {
name: 'Materials',
description: '',
count: 0,
css_class: 'fa-tint'
};
arrRequirements.forEach(function (requirement) {
if (requirement._data.name == 'Part') {
parts.description += requirement._data.description + ' (' + requirement._data.quantity + ')<br>';
parts.count++;
} else if (requirement._data.name == 'Material') {
materials.description += requirement._data.description + ' (' + requirement._data.quantity + ')<br>';
materials.count++;
} else if (requirement._data.name == 'Tooling') {
tools.description += requirement._data.description + ' (' + requirement._data.quantity + ')<br>';
tools.count++;
}
});
if (parts.description !== '') {
parts.description = parts.description.replace(/(<br>\s*)+$/);
} else {
parts.description = "No Parts requirements found";
}
if (materials.description !== '') {
materials.description = materials.description.replace(/(<br>\s*)+$/);
} else {
materials.description = "No Materials requirements found";
}
if (tools.description !== '') {
tools.description = tools.description.replace(/(<br>\s*)+$/);
} else {
tools.description = "No Tooling requirements found";
}
results.pushObject(parts);
results.pushObject(tools);
results.pushObject(materials);
});
return results;
}.property()
});
Currently it returns back the empty results array because it is waiting on the self.get promise to fulfill. If I return the result of self.get('requirements').then(...) then it returns the promise, not the results array and Ember isn't happy because it's not an array. What I want is for it to return back the populated results array.
The closest question I've found is here but it either doesn't solve the issue or I'm missing something.
You'll need to be using requirementSummary using an observable pattern, or after it's finished resolving.
Additionally this is not required due to requirements already being an iterable field:
var arrRequirements = requirements.get('content');
And you should be using a getter to get a property, not going to ._data.property
requirement.get('description')
Add this to your task template and you should see it populate (asynchronously):
{{#each requirement in requirementSummary}}
Name: {{requirement.name}} - Total: {{requirement.total}}
{{/each}}
The routes all seem to be working as well as the fixtures - I can use {{#each requirement in requirements}} and list each individual requirement with no issues. Just having the problem of generating the summarized property and accessing it after it's computed.
from routes/application_routes.js
this.resource( 'tasks', function () {
this.resource( 'task', { path: ':task_id' }, function () {
this.resource( 'task_requirements', { path: 'requirements' } );
} );
} );
from routes/task_routes.js
// List Tasks
App.TasksRoute = Em.Route.extend({
model: function () {
return this.store.find('task');
}
});
// Task Detail Route
App.TaskRoute = Em.Route.extend({
model: function(params) {
return this.store.find('task', params.task_id);
}
});
// Task Requirements Route
App.TaskRequirementsRoute = Em.Route.extend({
beforeModel: function () {
this.set('task', this.modelFor('task'));
}
});
Fixtures
// SAMPLE TASK FIXTURE.
App.Task.FIXTURES = [
{
"id": 1,
"name": "Test Task #1",
"description": "This is a test task. There are many like it but this one is mine.",
"requirements": [ 1, 2, 3, 4 ]
}
];
// SAMPLE REQUIREMENT FIXTURE
App.Requirement.FIXTURES = [
{
"id": 1,
"task_id": 1,
"type": "Part",
"description": "This is a Part requirement",
"quantity": 4
},
{
"id": 2,
"task_id": 1,
"type": "Part",
"description": "This is a Part requirement",
"quantity": 1
},
{
"id": 3,
"task_id": 1,
"type": "Material",
"description": "This is a Material requirement",
"quantity": 3
},
{
"id": 4,
"task_id": 1,
"type": "Tool",
"description": "This is a Tooling requirement",
"quantity": 1
}
];

Resources