Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angularjs ng-show based on callback

I'm new to angular so maybe I am missing something.

On my registration form I need a location from the user. Based on whether they allow/support navigator.geolocation, I want to show a drop down to choose a location.

Controller.

$scope.showLoc = true;
if(navigator && navigator.geolocation){
    navigator.geolocation.getCurrentPosition(function(pos){
        $scope.showLoc = false;
    },function(err){
        $scope.showLoc = true;
    });
}

and my form:

<form class="form-horizontal" name="register"  ng-controller="RegisterCtrl"  ng-submit="registerUser()"> .... 
<div ng-show="showLoc" accesskey="">
    test
</div>
....
 </form>

This approach is not working for me. Any insight would be appreciated.

like image 499
Maleck13 Avatar asked Dec 29 '12 19:12

Maleck13


1 Answers

Whenever you do some form of operation outside of angularjs, such as doing an ajax call with jquery, or grabbing the geolocation like your example here you need to let angular know to update itself. I looked at your jsfiddle and changed some of your code around to look like this:

var app = angular.module('myApp', []);
app.controller('RegisterCtrl',function($scope){
     $scope.showLoc = false;   
     navigator.geolocation.getCurrentPosition(function(pos){
             $scope.showLoc = true;
             $scope.$apply();
        },function(err){           
             $scope.showLoc = false;
             $scope.$apply();            
        });
});

And now showLoc changes to true on the update. Here's the documation on using the $apply() method http://docs.angularjs.org/api/ng.$rootScope.Scope#$apply

jsFiddle http://jsfiddle.net/yLFNP/6/

Edit: My answer was edited, but I don't agree with the edit. While you could wrap the $apply method around $scope.showLoc = false to make it "shorter" You're really only saving 1 character (the semi colon). Also, I tend to like the $apply method after a bunch of logic instead of wrapping everything in it. If there were more things I was doing to the scope, you'd either have to write each additional one like so:

$scope.$apply($scope.var1 = newValue1);
$scope.$apply($scope.var2 = newValue2);
$scope.$apply($scope.var2 = newValue3);

Which I find overkill, or you could use the function method:

$scope.$apply(function(){
    $scope.var1 = newValue1;
    $scope.var2 = newValue2;
    $scope.var3 = newValue3;
});

Or directly after code that needs "applying":

$scope.var1 = newValue1;
$scope.var2 = newValue2;
$scope.var3 = newValue3;
$scope.$apply();

By doing it this method all the time, you're code is easily transferable and very readable. Also less lines is not always the best method.

like image 191
Mathew Berg Avatar answered Oct 01 '22 07:10

Mathew Berg