Abiel Muren Abiel Muren - 10 months ago 55
AngularJS Question

Translate a native JS to Angularjs to calculate days between two dates?

I am having trouble trying to convert or translate a native js script to calculate number of days between two dates from two scopes ('work_start' and 'work_end') but did not have any success.

Here is the code, actually it works, but an alert is fired in the console.log and I am not achieving to solve this.

$scope.$watchGroup(['work_start', 'work_end'], function() {
var date1 = $scope.work_start;
var date2 = $scope.work_end;

// First we split the values to arrays date1[0] is the year, [1] the month and [2] the day
date1 = date1.split('-');
date2 = date2.split('-');

// Now we convert the array to a Date object, which has several helpful methods
date1 = new Date(date1[0], date1[1], date1[2]);
date2 = new Date(date2[0], date2[1], date2[2]);

// We use the getTime() method and get the unixtime (in milliseconds, but we want seconds, therefore we divide it through 1000)
date1_unixtime = parseInt(date1.getTime() / 1000);
date2_unixtime = parseInt(date2.getTime() / 1000);

// This is the calculated difference in seconds
var timeDifference = date2_unixtime - date1_unixtime;

// in Hours
var timeDifferenceInHours = timeDifference / 60 / 60;

// and finaly, in days :)
var timeDifferenceInDays = timeDifferenceInHours / 24;

// alert(timeDifferenceInDays);
$scope.total_days = timeDifferenceInDays;


And this is the alert I am receiving:

angular.js:13283 TypeError: Cannot read property 'split' of null
at app.js:3997
at c (angular.js:16419)
at m.$eval (angular.js:16884)
at m.$digest (angular.js:16700)
at m.$apply (angular.js:16992)
at g (angular.js:11313)
at y (angular.js:11511)
at XMLHttpRequest.t.onload (angular.js:11452)(anonymous function) @ angular.js:13283(anonymous function) @ angular.js:9996m.$digest @ angular.js:16702m.$apply @ angular.js:16992g @ angular.js:11313y @ angular.js:11511t.onload @ angular.js:11452

I changed some things but this is the far I can get. Any help will be welcome

Answer Source
Cannot read property 'split' of null

This means you're trying to use the split function on something that is not a String. So where are you using the split function?

date1 = date1.split('-');
date2 = date2.split('-');

So where are date1/2 defined?

var date1 = $scope.work_start;
var date2 = $scope.work_end;

So where are $scope.work_start/end defined? Not sure, but probably in html. To simply fix this issue, do something like this:

if(date1 === null || date2 === null){
  alert("no dates given")
} else {
  date1 = date1.split('-');
  date2 = date2.split('-');
  ... // rest of your code

Updating this section based on the discussion below...

Dates can be a pain in JS. A newly initialized date object is simply the number of milliseconds since January 1st, 1970 (UTC). If you're going to play with dates and times, look into a js library that makes Dates easier to work with like Moment or Sugar.

$watchGroup watches those two dates and runs the 'days between' functionality if either changes. This is fine, however you must compensate for a range of issues, such as

the user changes work_start before work_end, and work_start is after work_end

the user enters a date that is not in the correct format

and a bunch of other stuff that can come up. You might want to think about incorporating a button to allow the user to update the dates after they're finished editing both. This will also allow your form to error-check the input, and not allow a submission if it's not in the correct format.


<div ng-controller="workCont">
  <input ng-model="$scope.work_start"></input>
  <input ng-model="$scope.work_end"></input>
  <button ng-click="$scope.getDaysBetween()">Get Days Between</button>
  <p>Days Between: {{$scope.daysBetween}}</p>


var workApp = angular.module('workApp', []);

workApp.controller('workCont', function workCont($scope) {
  $scope.work_start = new Date();
  $scope.work_end = new Date();
  $scope.daysBetween = 0;
  $scope.getDaysBetween = function(){
    var date1 = $scope.work_start
    var date2 = $scope.work_end
    var timeDiff = Math.abs(date2.getTime() - date1.getTime());
    var diffDays = Math.ceil(timeDiff / (1000 * 3600 * 24)); 
    $scope.daysBetween = diffDays

Thanks to "Get difference between 2 dates in javascript?" for the getDaysBetween logic.