0

I have this controller in angularJs

.controller('MapCtrl', function($scope, $http, $rootScope) {
  $scope.mappa={};
  var curPos;

  if (navigator.geolocation)
      navigator.geolocation.getCurrentPosition(success);

    function success(pos) {
      var crd = pos.coords;
      curPos = crd.latitude;
    };

    console.log(curPos);
})

The conole.log gives me an undefined. I know that this could be an obvious question for someone but how can I solve this?

EDIT

Sorry guys, I wasn't so clear: I need to use the curPos var outside the function. Once it has been enhanced I need to read its value everywhere in the controller.

  • Since you are working with asynchronous function you can't print the `curPos` like the way you did. Refer [return response from async call](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call?rq=1) – Gangadhar Jannu Mar 21 '17 at 13:42
  • Possible duplicate of [How do I return the response from an asynchronous call?](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Gangadhar Jannu Mar 21 '17 at 13:42

5 Answers5

0

navigator.geolocation.getCurrentPosition is aysnchronous, so by the time your success function is executed, your console.log(curPos) is getting executed, hence undefined. Just put console.log(curPos) inside your success function.

.controller('MapCtrl', function($scope, $http, $rootScope) {
   $scope.mappa={};
   var curPos;

  if (navigator.geolocation)
  navigator.geolocation.getCurrentPosition(success);

   function success(pos) {
      var crd = pos.coords;
      curPos = crd.latitude;
      console.log(curPos);
   };


})
Pramod_Para
  • 671
  • 3
  • 10
0

I assume the 'getCurrentPosition' is some sort of service call and hence your success call back is being called asynchronously (after the promise returned from service).

So, move your logic, where you are using 'curPos' variable, to your success call back function. There you will have the updated value of 'curPos'.

.controller('MapCtrl', function($scope, $http, $rootScope) {
    $scope.mappa = {};
    var curPos;

    if (navigator.geolocation)
        navigator.geolocation.getCurrentPosition(success);

    function success(pos) {
        var crd = pos.coords;
        curPos = crd.latitude;
        console.log(curPos); // would be a defined value here
        // your logic goes here
    };

    console.log(curPos); // would be undefined as it is being called before the execution of success call back function
})

It also depends on the cases you need to work on.

  1. If this value of 'curPos' is fetched once:

    a. At the time of app start up - then fetch this value in somoe home controller or the parent / abstract controller and save it in some factory (shared data service), which then can be fetched from any of the controllers as when required.

    b. At the time of page load - then this can be fetched before the page load using anguler ui router states and resolves. Refer http://www.jvandemo.com/how-to-resolve-angularjs-resources-with-ui-router/ for more details.

  2. If the value needs to be updated every now and then - in this case you will have to move your every logic (which uses this variable) to success call back (can implement multiple call backs depending upon the variation in logic), by this you would be explicitly synchronizing this scenario.

Sachet Gupta
  • 822
  • 5
  • 18
0

Use $scope.$apply to update your scope in an async method no handled by Angular framework.

Here is a working example :

Plunker : https://plnkr.co/edit/xiv33CunDZrb06PvfFyU

script.js

angular.module('app', []);

angular.module('app').controller('SampleController', function ($scope) {
    var ctrl = this;

    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(
          // On success
          function(pos) {
            console.log(pos)
            $scope.$apply(function() {
                $scope.coords = pos.coords;
            })
          }, 
          // On error
          function(err) {
            console.error(err)
          }
      );
    }
});

index.html

<html lang="en" ng-app="app">
<head>
  <meta charset="utf-8">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>
  <script src="scripts.js"></script>
</head>

<body ng-controller="SampleController as ctrl">

<p>
    latitude: {{coords.latitude}} <br/>
    longitude: {{coords.longitude}} <br/>
</p>

</body>
</html>
Stephane Janicaud
  • 3,531
  • 1
  • 12
  • 18
0

Since its an async process, if you print the var without waiting success of getCurrentPosition, it will be undefined. You have to print it after this callback (or inside it). Futhermore, if you want access to this var, first you have to check if its defined, if its not, wait for it. You can play with angular $timeout and vars to print the console when the var is ready.

0

I don't know exactly why, but I finally make it work just by using angular.copy

    var curPos = {};

      navigator.geolocation.getCurrentPosition(function(pos) {
        var tmpPos = {
                  lat: pos.coords.latitude,
                  lng: pos.coords.longitude
        }

        angular.copy(tmpPos, curPos);
      });

      console.log(curPos);

I had to put all the code which uses that var inside the success function. Thanks to everyone :)