1
\$\begingroup\$

I'm returning an array containing dates (and other things) from an API, then looping through the array on the front end to convert them into dates

The backend uses Node.Js and queries a mySql database with the mySql module:

pool.getConnection(function(err, conn) {
  conn.query('SELECT * FROM myData’, function(err, result) {
    if (result) {
      res.json(result);
    }
    conn.release();
  });
});

An Angular.js front end accesses the Express API.

var _getCases = function() {
  return $http.get('/api/case');
};

But the dates are all strings. Here’s an example of what's received in Angular:

[
  {
    id: 1,
    fruit: “apple”,
    createdOn: "2016-09-02T23:00:00.000Z"
  },
  {
    id: 2,
    fruit: “banana”,
    createdOn: "2016-09-11T23:00:00.000Z”
  },
  {
    id: 3,
    fruit: “cherry”,
    createdOn: "2016-09-13T23:00:00.000Z"
  },
]

I'm converting all the dates to strings in a loop but this seems inefficient. Is there a better way?

var a = $http.get('/api/case');

for(var i in a){
  a[i].createdOn = new Date(a[i].createdOn);
};

return a;
\$\endgroup\$
  • \$\begingroup\$ I'll suggest you to create a method on controller $scope and call it when showing date in HTML. Ex. in controller $scope.getDate = function(str) { return new Date(str);}; and in HTML <span>{{getDate(fruit.createdOn)}}</span> \$\endgroup\$ – Tushar Sep 27 '16 at 10:45
  • \$\begingroup\$ Thanks, so better to change the view than change the data? \$\endgroup\$ – Geraint Sep 27 '16 at 10:49
  • 1
    \$\begingroup\$ If you just want to show the date to user, this is good. If you want to use the Date in JS too, use forEach or map to iterate over array and parse the date. \$\endgroup\$ – Tushar Sep 27 '16 at 11:46
  • 2
    \$\begingroup\$ Are you sure this is working code? $http.get is async. You cannot simply return the result from an async operation. \$\endgroup\$ – Joseph Sep 27 '16 at 14:56
  • \$\begingroup\$ @JosephtheDreamer yeh, it's in the service and the is used by the controller, like this: serviceName._getCases().then(function(res) { $scope.someData = res.data }); \$\endgroup\$ – Geraint Sep 27 '16 at 15:11
1
\$\begingroup\$

Firstly, regardless of whether you actually want to transform the fields into dates,you will need to format them for display. This formatting should be applied in the template. In such cases, the idiomatic approach is to define a filter.

angular.filter('formatAsDate', ...);

and then inject the filter into the views controller to make it available.

MyController.$inject = ['formatAsDate'];
function MyController(formatAsDate) { }

However, date formatting is such a common scenario that AngularJS provides a built in, globally available (does not need to be injected) date filter out of the box.

Its first argument is a value representing a date. This may either be a Date, an ISO formatted date string such as you have, or a number in milliseconds. Its second argument is a format string which specifies how the date should be displayed.

for example

{{'2016-09-02T23:00:00.000Z' | date: 'EEEE MMMM dd, yyyy'}}

will render

Friday September 02, 2016
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.