1

Im trying to pass the date from a date picker value into a $http session parameter (like "2017-12-7"), but the date my datepicker Date variable is 'undefined'

angular.module('MyApp', ['ngMaterial']).controller('MyController',
            function($scope, $http) {                   

                  this.myDate = new Date();
                  this.minDate = new Date("December 4, 2017");
                  this.maxDate = new Date("December 10, 2017");

                  $scope.getDataFromServer = function() {

                      var dt = this.myDate;

                        $http({

                            method : 'GET',
                            url : 'myurl',
                            params : {
                                pdate : this.myDate
                            }
                        }).then(function mySuccess(response) {
                            $scope.datacontainer= response.data;
                        }, function myError(response) {

                        });
                    };

        });

The $scope.getDataFromServer method is called when you click a button. The following line var dt = this.myDate; was to look at the myDate object in chrome DevTools (F12) and it says 'undefined'.

The date picker HTML is as follows:

<div flex="20">
  <md-datepicker ng-model="myDate" md-placeholder="Enter date" md-min-date="ctrl.minDate" md-max-date="ctrl.maxDate">
  </md-datepicker>
</div>
2
  • 1
    try preserving parent this before using like var myContext = this; and get myContext.myDate Commented Jan 1, 2018 at 14:22
  • 1
    @beaumondo - You probably defined the controller like MyApp as ctrl in the view, so you need to set the modal like this: ng-model="ctrl.myDate". In the controller itself, put on the very top line of the controller function this: var ctrl = this; and then change all the current this and $scope to ctrl so your code will be more readable. Don't forget the add the ctrl. prefix for any other controller properties in the VIEW Commented Jan 1, 2018 at 14:41

2 Answers 2

3

this.myDate is evaluated to undefined here because this is in different context when getDataFromServer is executed. The problem here is you have initialized myDate inside MyController and function is defined inside $scope. Read more about the difference here.

getDataFromServer cannot see myDate as its created inside MyController.

Solution:

Define them both in same context.

angular.module('MyApp', ['ngMaterial']).controller('MyController',
        function($scope, $http) {                   
              var ctrl = this;
              ctrl.myDate = new Date();
              ctrl.minDate = new Date("December 4, 2017");
              ctrl.maxDate = new Date("December 10, 2017");

              ctrl.getDataFromServer = function() {

                  var dt = ctrl.myDate;

                    $http({

                        method : 'GET',
                        url : 'myurl',
                        params : {
                            pdate : ctrl.myDate
                        }
                    }).then(function mySuccess(response) {
                        ctrl.datacontainer= response.data;
                    }, function myError(response) {

                    });
                };

    });

Example:

angular.module('MyApp',['ngMaterial', 'ngMessages', 'material.svgAssetsCache']).controller('AppCtrl', function($scope, $http) {
  var ctrl =this;
  ctrl.myDate = new Date();
  ctrl.value="No Date Selected";
  ctrl.getDataFromServer = function() {
    ctrl.value = ctrl.myDate;
  }
});
<link href="https://material.angularjs.org/1.1.5/docs.css" rel="stylesheet"/>
<link href="https://cdn.gitcdn.link/cdn/angular/bower-material/v1.1.5/angular-material.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-animate.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-route.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-aria.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-messages.min.js"></script>
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/t-114/svg-assets-cache.js"></script>
<script src="https://cdn.gitcdn.link/cdn/angular/bower-material/v1.1.5/angular-material.js"></script>

<md-content ng-controller="AppCtrl as ctrl" layout-padding="" ng-cloak="" class="datepickerdemoBasicUsage" ng-app="MyApp">
  <div layout-gt-xs="row">
    <div flex-gt-xs="">
      <h4>Standard date-picker</h4>
      <md-datepicker ng-model="ctrl.myDate" md-placeholder="Enter date"></md-datepicker>
    </div>
    <md-button class="md-raised" ng-click="ctrl.getDataFromServer()">Print</md-button>
  </div>
  {{ctrl.value}}
</md-content>

Sign up to request clarification or add additional context in comments.

3 Comments

I would recommend to save a reference to this at the first line of the controller (i.e var ctrl = this; or var vm = this;) and use that reference throughout the controller, this will ensure that you don't lose the reference to the controller in inner functions, so you could change $scope.datacontainer= response.data; to ctrl.datacontainer= response.data; in the success callback of the ajax call
@AlonEitan Thanks for suggestion. Modified answer to reflect the changes.this reference is one of the easily confused aspect of JS.
Good call, solution worked well. I thought because it was a nested function inside the controller all local variable were accessible
0
angular.module('MyApp', ['ngMaterial']).controller('MyController',
        function($scope, $http) {                   
              var that = this;
              that.myDate = new Date();
              that.minDate = new Date("December 4, 2017");
              that.maxDate = new Date("December 10, 2017");

              $scope.getDataFromServer = function() {
                  var dt = that.myDate;

                    $http({

                        method : 'GET',
                        url : 'myurl',
                        params : {
                            pdate : that.myDate
                        }
                    }).then(function mySuccess(response) {
                        $scope.datacontainer = response.data;
                    }, function myError(response) {

                    });
                };

    });

1 Comment

What is this, an answer or what? Read How to Answer, explain what you changed, the OP is not supposed to guess your explanation. And BTW, you have a bug in your answer, and it shouldn't solve anything at all

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.