How can I use geolocation watchPosition in angularjs? - angularjs

i want to use the geolocation.watchPosition in angular js in order to find my new location every 3minutes something like gps tracker. Can anyone help me please?

appControllers.controller('Ctrl', ['$scope','$routeParams', '$http','$window','$interval',
function geo_success(position) {
var lat = position.coords.latitude;
var lng = position.coords.longitude;
console.log(lat);
console.log(lng);
$scope.$apply(function(){
$scope.lat = lat;
$scope.lng = lng;
});
$scope.latlng = function(){
$http.post('/profile', {
latitude: $scope.lat,
longitude: $scope.lng
})
.success(function(user){
// No error: authentication OK
$rootScope.message = 'Lat/Lng send ok!';
})
.error(function(){
// Error: authentication failed
$rootScope.message = 'Lat/Lng dont send';
});
};
}
function geo_error(error){
console.log ("gps lost");
}
var watchID = $window.navigator.geolocation.watchPosition(geo_success,geo_error, {enableHighAccuracy: true });
}]);
this i have write

Hope this could help.
angular.module("GeoService",[]).
factory('GeoLocation',['$rootScope', '$window', '$q', '$resource', function($rootScope, $window, $q, $resource){
var _geoCapable = false,
_deferred = $q.defer(),
_errorMsg = null;
//Geolocation options
_option = {
enableHighAccuracy:true,
timeout: 5000,
maximumAge: 0,
desiredAccuracy: 0,
frequency: 1
};
if($window.navigator && $window.navigator.geolocation){
_geoCapable = true;
}
if(!_geoCapable){
$rootScope.$broadcast('geo:error', 'Geolocation not supported');
}
//Geolocation function onSucces
_onSucces = function (position) {
_deferred.resolve(position);
};
//Geolocation function onFail
_onFail = function (error) {
switch (error.code) {
case error.PERMISSION_DENIED:
_errorMsg = "User denied the request for Geolocation."
break;
case error.POSITION_UNAVAILABLE:
_errorMsg = "Location information is unavailable."
break;
case error.TIMEOUT:
_errorMsg = "The request to get user location timed out."
break;
case error.UNKNOWN_ERROR:
_errorMsg = "An unknown error occurred."
break;
};
$rootScope.$broadcast('geo:error', _errorMsg);
_deferred.reject(_errorMsg);
};
//Service API
var _locationService = {
//getPosition() function:
getLocation: function(){
if(!_geoCapable){
return _deferred.reject();
};
$window.navigator.geolocation.getCurrentPosition(_onSucces,_onFail,_option);
return _deferred.promise;
},
//watchPosition() function:
watchPosition: function(){
if(!_geoCapable){
$rootScope.$broadcast('geo:error','Geolocation not supported');
};
$window.navigator.geolocation.watchPosition(function(position){
$rootScope.$broadcast('geo:positionUpdate', position);
}, _onFail);
}
};
return _locationService;
}]);

Related

Angular leaflet - Showing multiple marker issue

I am using the following code to add markers in leaflet:
.controller('MapController',
[ '$scope',
'$cordovaGeolocation',
'$stateParams',
'$ionicModal',
'$ionicPopup',
'$http',
function(
$scope,
$cordovaGeolocation,
$stateParams,
$ionicModal,
$ionicPopup,
$http
) {
$scope.$on("$stateChangeSuccess", function() {
$scope.map = {
defaults: {
tileLayer: 'http://{s}.tile.osm.org/{z}/{x}/{y}.png',
maxZoom: 18,
zoomControlPosition: 'bottomleft'
},
markers : {},
events: {
map: {
enable: ['context'],
logic: 'emit'
}
}
};
$scope.locate();
});
$scope.locate = function(){
$scope.map.center = {
lat : location.lat,
lng : location.lng,
zoom : 12,
};
var Location = function() {
if ( !(this instanceof Location) ) return new Location();
this.lat = "";
this.lng = "";
this.name = "";
};
$ionicModal.fromTemplateUrl('templates/addLocation.html', {
scope: $scope,
animation: 'slide-in-up'
}).then(function(modal) {
$scope.modal = modal;
});
$scope.map.markers.push=({
lat:35.654,
lng:73.244,
message:'demo 1'
})
$scope.map.markers.push=({
lat:38.654,
lng:73.244,
message:'demo 2'
})
$scope.$on('leafletDirectiveMap.click', function(event, locationEvent){
$scope.newLocation = new Location();
$scope.newLocation.lat = locationEvent.leafletEvent.latlng.lat;
$scope.newLocation.lng = locationEvent.leafletEvent.latlng.lng;
$scope.modal.show();
});
$scope.saveLocation = function(lat, lang) {
//LocationsService.savedLocations.push($scope.newLocation);
//alert(lat + " - " + lang);
var link = 'http://192.168.5.110/server/addLocation.php';
var json1 = {l1 : lat, l2 : lang , l3: sessionStorage.getItem('loggedin_phone')};
$http.post(link, { data: json1 })
.then(function (res){
$scope.response = res.data.result;
if($scope.response.created=="1"){
$scope.title="Thank You";
$scope.template="Mobile Toilet Added!";
//no back option
/*
$ionicHistory.nextViewOptions({
disableAnimate: true,
disableBack: true
});
$state.go('login', {}, {location: "replace", reload: true});
*/
}else if($scope.response.exists=="1"){
$scope.title="Duplication";
$scope.template="This Location is already added!";
}else{
$scope.title="Failed";
$scope.template="Contact Our Technical Team";
}
var alertPopup = $ionicPopup.alert({
title: $scope.title,
template: $scope.template
});
});
$scope.modal.hide();
};
$cordovaGeolocation
.getCurrentPosition()
.then(function (position) {
$scope.map.center.lat = position.coords.latitude;
$scope.map.center.lng = position.coords.longitude;
$scope.map.center.zoom = 18;
$scope.map.markers.now = {
lat:position.coords.latitude,
lng:position.coords.longitude,
focus: true,
draggable: false,
//message: ''
};
}, function(err) {
// error
console.log("Location error!");
console.log(err);
});
};
}]);
But only the demo2 marker is displaying.
Is there a way to show multiple markers on the leaflet map by using JSON data of latitudes and longitudes loaded from API?
<leaflet defaults="defaults" event-broadcast="events" lf-center="center" markers="markers" layers="layers" id="global-map" width="100%" height="240px"></leaflet>
<leaflet defaults="defaults2" event-broadcast="events2" lf-center="center2" markers="markers2" layers="layers2" id="global-map2" width="100%" height="240px"></leaflet>

AngularJS passing data between controllers

I have spent hours trying to figure out how to pass data between controllers. Can someone please help me out?
This is the entirety if my angularjs file:
var app = angular.module('FitnessApp', []);
var HTTP_RESPONSE = function(response) { return response.data || response; };
var HTTP_ERROR = function(err) {return err; };
app.service('Share', ['$rootScope', '$timeout', function($rootScope, $timeout) {
var user = null;
var viewUser = null;
return {
setUser: function(newUser) {user = newUser; return $rootScope.$broadcast('user:updated'); },
getUser: function() {return user;},
setSearchedUser: function(searchedUser) {
viewUser = searchedUser; console.log(viewUser);
$timeout(function(){
return $rootScope.$broadcast('user:searched');
}, 5000);
//return $rootScope.$broadcast('user:searched');
},
getSearchedUser: function() {return viewUser;}
};
}]);
app.service('UserFactory', ['$http', function($http){
return {
// checkUserExists: function(user) {
// return $http.get('/user/exists', user).then(HTTP_RESPONSE, HTTP_ERROR);
// },
/*updateRating: function(id, rating) {
return $http.put('/user/updateRating', {_id: id, rating: rating}).then(HTTP_RESPONSE, HTTP_ERROR);
},*/
userLogIn: function(user) {
return $http.post('/user/login', user).then(HTTP_RESPONSE, HTTP_ERROR);
},
getUser: function(user_id) {
return $http.get('/user/userProfile/' + user_id).then(HTTP_RESPONSE, HTTP_ERROR);
},
userSignup: function(user) {
return $http.post('/user/adduser', user).then(HTTP_RESPONSE, HTTP_ERROR);
},
userEdit: function(user) {
return $http.put('/user/updateUser', user).then(HTTP_RESPONSE, HTTP_ERROR);
},
userChangeEmail: function(user) {
return $http.put('/user/changeEmail', user).then(HTTP_RESPONSE, HTTP_ERROR);
},
userChangePassword: function(user) {
return $http.put('/user/changePassword', user).then(HTTP_RESPONSE, HTTP_ERROR);
},
userDelete: function(del) {
return $http.put('/user/deleteUser/', del).then(HTTP_RESPONSE, HTTP_ERROR);
},
/*trainerLogin: function(trainer) {
return $http.post('/trainer/login', trainer).then(HTTP_RESPONSE, HTTP_ERROR);
},*/
trainerSignup: function(trainer) {
return $http.post('/trainer/addTrainer', trainer).then(HTTP_RESPONSE, HTTP_ERROR);
},
findUser: function(email) {
return $http.get('/user/findByEmail/' + email).then(HTTP_RESPONSE, HTTP_ERROR);
},
updateRating: function(idUser, idViewed, rating) {
return $http.put('/user/updateRating', {_id_user: idUser, _id_viewed: idViewed, rating: rating}).then(HTTP_RESPONSE, HTTP_ERROR);
},
getRating: function(idUser, idViewed) {
return $http.put('/user/getRating', {_id_user: idUser, _id_viewed: idViewed}).then(HTTP_RESPONSE, HTTP_ERROR);
}
};
}]);
// service that contains the ajax query
app.service('TrainerFactory', ['$http', function($http) {
return {
trainerAddEvent: function(trainerEvent) {
return $http.post('/trainer/addEvent', trainerEvent).then(HTTP_RESPONSE, HTTP_ERROR);
}
};
}]);
// controller which injects the above service
app.controller('EventController', ['$scope', 'TrainerFactory', 'Share', function($scope, TrainerFactory, Share) {
$scope.trainerAddEvent = function(newEvent) {
TrainerFactory.trainerAddEvent(newEvent).then(function(response) {
window.location.replace('/');
}, function(err) {}).finally(function() {});
};
}]);
app.controller('RootController', ['$scope', '$window', 'UserFactory', 'Share', function($scope, $window, UserFactory, Share) {
$scope.initUser = function(user_id) {
UserFactory.getUser(user_id).then(function(response) {
Share.setUser(response);
}, function(err) {
console.log(err);
}).finally(function(){});
};
$scope.$on('user:updated', function(data) {
$scope.user = Share.getUser();
});
$scope.findUser = function(email) {
UserFactory.findUser(email).then(function(response) {
switch(response.status) {
case 200:
Share.setSearchedUser(response.data);
// gets the user object from users.js '/user/findByEmail/:email'
// $scope.viewUser = response.data;
// $scope.showme = true;
// // gets the user's average rating
// $scope.userAverage = response.data.rating;
//********************************************************************* this will need to change when we go live
$window.location.href = "http://10.0.0.25:8001/user/profile/";
break;
case 404:
// User not found
$scope.login_err = 'Email not found, please try again';
break;
default:
$scope.login_err = 'An unexpected Error has occurred, please try again later.';
}
}, function(err) {
}).finally(function(){});
};
}]);
app.controller('ViewProfileController', ['$scope', 'UserFactory', 'Share', function($scope, SearchFactory, Share) {
$scope.viewUser = Share.getSearchedUser(); console.log($scope.viewUser);
// gets the current user
$scope.$on('user:updated', function(data) {
$scope.user = Share.getUser();
});
$scope.$on('user:searched', function(data) {console.log('here');
$scope.viewUser = Share.getSearchedUser(); console.log($scope.viewUser);
});
$scope.updateRating = function(idUser, idViewed, rating) {
UserFactory.updateRating(idUser, idViewed, rating).then(function(response) {
// update rating for front end
$scope.userAverage = response.data;
}, function(err) {
}).finally(function() {});
};
$scope.getRating = function(idUser, idViewed) {
UserFactory.getRating(idUser, idViewed).then(function(response) {
// relay the current user's rating of the user being viewed
console.log(response.data);
$scope.rating = response.data;
}, function(err) {
}).finally(function() {});
};
}]);
app.controller('SignupController', ['$scope', 'UserFactory', 'Share', function($scope, UserFactory, Share) {
$scope.sayHello = function() {
console.log('hello!');
};
$scope.$on('user:updated', function(data) {
$scope.user = Share.getUser();
});
$scope.clearMessages = function(messages) {
messages.forEach(function(message) {
message = null;
});
};
// Login
$scope.userLogin = function(user) {
UserFactory.userLogIn(user).then(function(response) {
switch(response.status) {
case 200:
// Okay to proceed
window.location.replace('/');
break;
case 406:
// Okay to proceed
window.location.replace('/newTrainer');
break;
case 404:
// User not found
$scope.login_err = 'Email not found, please try again';
break;
case 401:
// Password incorrect
$scope.login_err = 'Incorrect password, please try again';
break;
case 400:
// Invalid request
break;
default:
$scope.login_err = 'An unexpected Error has occurred, please try again later.';
}
}, function(err) {}).finally(function() {
});
};
// Signup
$scope.userSignup = function(user) {
UserFactory.userSignup(user).then(function(response) {
switch(response.status) {
case 200:
// Okay to proceed
window.location.replace('/');
break;
case 401:
// User already exists
$scope.signup_err = 'Email unavailable or invalid, please try again';
return;
case 400:
// Invalid Request
$scope.signup_err = 'An Error has occurred, please contact support#smb.com for help.';
break;
default:
$scope.signup_err = 'An unexpected Error has occurred, please try again later';
}
}, function(err) {}).finally(function() {});
};
$scope.trainerSignup = function(newTrainer) {
UserFactory.trainerSignup(newTrainer).then(function(response) {
switch(response.status) {
case 200:
// Okay to proceed
window.location.replace('/newTrainer');
break;
case 401:
// User already exists
$scope.signup_err = 'Email unavailable or invalid, please try again';
return;
case 400:
// Invalid Request
$scope.signup_err = 'An Error has occurred, please contact support#smb.com for help.';
break;
default:
$scope.signup_err = 'An unexpected Error has occurred, please try again later';
}
}, function(err) {}).finally(function() {});
};
}]);
app.controller('ProfileController', ['UserFactory', 'Share', '$scope', function(UserFactory, Share, $scope) {
$scope.$on('user:updated', function() {
$scope.user = Share.getUser();
});
/*$scope.updateRating = function(id, rating) {
return UserFactory.updateRating(id, rating).then(function(response) {
//$scope.user.rating.push(rating);
}, function(err) {
}).finally(function() {});
};*/
$scope.updateUser = function(updatedUser) {
return UserFactory.userEdit(updatedUser).then(function(response) {
$scope.message = 'Success!';
}, function(err) {
}).finally(function() {});
};
$scope.changeEmail = function(updatedUser) {
return UserFactory.userChangeEmail(updatedUser).then(function(response) {
}, function(err) {}).finally(function() {});
};
$scope.changePassword = function(updatedUser) {
return UserFactory.userChangePassword(updatedUser).then(function(response) {
}, function(err) {}).finally(function() {});
};
$scope.deleteUser = function(user) {
UserFactory.userDelete(user).then(function(response) {
switch(response.status) {
case 200:
window.location.replace('/user/signup');
break;
case 404:
$scope.del_err = 'Wrong Email, please try again';
break;
default:
$scope.del_err = 'An unexpected error occurred, please try again later';
}
}, function(err) {}).finally(function() {
console.error(err);
});
};
}]);
app.service('ActivityService', ['$http', function($http) {
return {
addActivity: function(activity) {
return $http.put('/user/addActivity', {activity: activity}).then(HTTP_RESPONSE, HTTP_ERROR);
},
removeActivity: function(activity) {
return $http.put('/user/removeActivity', {activity: activity}).then(HTTP_RESPONSE, HTTP_ERROR);
},
hasInterest: function(activity, array) {
var found = false;
array.forEach(function(interest) {
found = found || activity === interest;
});
return found;
}
};
}]);
app.controller('ActivityController', ['$scope', 'Share', 'ActivityService', function($scope, Share, ActivityService) {
$scope.$on('user:updated', function() {
$scope.user = Share.getUser();
});
$scope.addActivity = function(activity) {
return ActivityService.addActivity(activity).then(function(response) {
$scope.user.activities.push(activity);
}, function(err) {
}).finally(function() {});
};
$scope.removeActivity = function(activity) {
return ActivityService.removeActivity(activity).then(function(response) {
console.log(response);
$scope.user.activities = $scope.user.activities.filter(function(act) {
console.log(act, activity);
return activity !== act;
});
}, function(err) {
}).finally(function() {});
};
$scope.hasInterest = function(interest) {
return ActivityService.hasInterest(interest, $scope.user.activities);
};
}]);
app.service('MapService', function() {
return {
};
});
app.controller('MapController', ['$scope', 'Share', 'MapService', function($scope, Share, MapService) {
}]);
I am trying to pass information about the user object from the RootController to the ViewProfile Controller.
I think a problem I may be having is that switching the view may be destroying the variable?
Can someone please point me in the right direction?
Here is layout.jade which uses RootController:
doctype html
html
head
title= title
link(rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css')
link(rel='stylesheet', href='/stylesheets/style.css')
link(rel='stylesheet' type='text/css' href='/stylesheets/jquery.datetimepicker.css')
link(rel='stylesheet' type='text/css' href='/stylesheets/ratings.css')
block loadfirst
script(src="https://code.jquery.com/jquery-1.12.3.min.js"
integrity="sha256-aaODHAgvwQW1bFOGXMeX+pC4PZIPsvn2h1sArYOhgXQ=" crossorigin="anonymous")
script(src='https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js')
script(src='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js')
script(src='/angular/fitnessapp.js')
body
div#wrapper(ng-app='FitnessApp')
div#header(ng-controller='RootController' ng-init='initUser(#{JSON.stringify(user)})')
nav.navbar.navbar-default
div.container-fluid
// Brand and toggle get grouped for better mobile display
div.navbar-header
button.navbar-toggle.collapsed(type='button', data-toggle='collapse', data-target='#bs-example-navbar-collapse-1', aria-expanded='false')
span.sr-only Toggle navigation
span.icon-bar
span.icon-bar
span.icon-bar
a.navbar-brand(href='/') SpotMeBro
// Collect the nav links, forms, and other content for toggling
div#bs-example-navbar-collapse-1.collapse.navbar-collapse
ul.nav.navbar-nav
li.dropdown
a.dropdown-toggle(href='#', data-toggle='dropdown', role='button', aria-haspopup='true', aria-expanded='false')
| Dropdown
span.caret
ul.dropdown-menu
li
a(href='#') {{user.type}}
li
a(href='#') Another action
li
a(href='#') Something else here
li.divider(role='separator')
li
a(href='#') Separated link
li.divider(role='separator')
li
a(href='#') One more separated link
form.navbar-form.navbar-left(role='search')
.form-group
input.form-control(type='text', placeholder='Search for an event')
button.btn.btn-default(type='submit') Submit
ul.nav.navbar-nav.navbar-right
if(!user)
li
a(href='/user/signup') Login/Signup
li
a(href='/trainer/signup') Trainer Signup
else
li
a(href='/user/search/') Search
li
a(ng-if='user.type' href='/trainer/createEvent') Create Event
li
a(href='/user/profile/') Profile
li
a(href='/user/interests') Interests
li
a(href='/user/settings') Settings
li
a(href='/logout') Logout
div
form.navbar-form.navbar-right(name='search' ng-submit="search.$valid && findUser(email);" novalidate)
div.form-group
div.input-group
input#email.form-control(name='email' ng-model='email' type='email' required)
button.btn.btn-default(type='submit') Search
div(ng-show='search.$submitted')
span.text-danger(ng-show='search.email.$error.required')
| Please enter an email.
span.text-danger(ng-show='search.email.$error.email')
| Please enter an email.
// /.navbar-collapse
// /.container-fluid
div#body
block content
div#footer
div.container-fluid.text-center
span.text-center Fütr
block scripts
And here is userProfile.jade which uses ViewProfileController:
extends layout
block content
div.container(ng-controller='ViewProfileController')
//- legend Search for user by email
//- form(name='search' ng-submit='search.$valid && findUser(email)' novalidate)
//- div.form-group
//- div.input-group
//- label(for='Email') Email
//- input#email.form-control(name='email' ng-model='email' type='email' required)
//- div(ng-show='search.$submitted || search.email.$touched')
//- span.text-danger(ng-show='search.email.$error.required')
//- | Please enter an email.
//- span.text-danger(ng-show='search.email.$error.email')
//- | Please enter an email.
//- div.form-group
//- button.btn.btn-primary(type='submit') Search
div
legend {{viewUser.firstName}} {{viewUser.lastName}}'s Profile {{user.email}} {{viewUser.email}}
div
span Email: {{viewUser.email}}
br
span Join Date: {{viewUser.joinDate}}
div
//img(src= "http://img.ifcdn.com/images/8c70c2b66b7a52154bb3d3faadf03995c2c1e5ca0144a8979c834e61a1e166f5_1.jpg" width="250" height="250")
img(src= "http://us.123rf.com/450wm/arcady31/arcady311212/arcady31121200002/16708573-anonymous-vector-sign.jpg" width="250" height="250")
div(ng-if='showme===true')
div(ng-init='getRating(user._id, viewUser._id)')
div#star-div {{viewUser.firstName}}'s average rating: {{userAverage}}
br
div(ng-if='user.email != viewUser.email')
span.star-rating
input(ng-change='updateRating(user._id, viewUser._id, rating);' ng-model='rating' type='radio', name='rate', value='1')
i
input(ng-change='updateRating(user._id, viewUser._id, rating);' ng-model='rating' type='radio', name='rate', value='2')
i
input(ng-change='updateRating(user._id, viewUser._id, rating);' ng-model='rating' type='radio', name='rate', value='3')
i
input(ng-change='updateRating(user._id, viewUser._id, rating);' ng-model='rating' type='radio', name='rate', value='4')
i
input(ng-change='updateRating(user._id, viewUser._id, rating);' ng-model='rating' type='radio', name='rate', value='5')
i
br
div Interests
br
label.label.label-default {{viewUser.activities}}
br
div Member Since
br
label.label.label-default {{viewUser.joinDate}}
br
div About Me
br
label.label.label-default {{viewUser.about}}
br
div RSVP'D Activities
br
label.label.label-default {{viewUser.upcomingActivities}}
br
div Past Activities
br
label.label.label-default {{viewUser.pastActivities}}
br
With your current navigation every time you navigate to a page the HTML sent back from the server will include everything from layout.jade.
Since this contains ng-app your application will restart and everything will be reset, including the variables in your service.
I recommend that you look into ngRoute instead for navigation.

Angular Service or Root Function

I want to re-organize my code so that I can share a dialog page with different controllers (ie. each controller opens the same dialog)
Should my dialog be a service or a directive... I'm not sure how to make it available to the controllers and have access to scopes
Something like this:
app.controller('PropertiesCtrl', function($scope,$rootScope,$http, DTOptionsBuilder, DTColumnBuilder, apiserv, $filter, $mdDialog, $mdMedia){
$scope.getProperties = function(){
$scope.data=[];
//var url = 'http://www.filltext.com/?rows=10&fname={firstName}&lname={lastName}&delay=3&callback=JSON_CALLBACK';
var data = "?db="+ $rootScope.globals.currentUser.agents[$rootScope.globals.currentDB].db_name;
var url = apiserv+"api.properties.test.php"+data;
$http.jsonp(url).success(function(data){
$scope.data=data;
});
};
var vm = this;
function stateChange(iColumn, bVisible) {
console.log('The column', iColumn, ' has changed its status to', bVisible);
}
// TO-DO: Rather load from a Factory promise, like here: https://github.com/l-lin/angular-datatables/issues/14
// Example here: http://embed.plnkr.co/B9ltNzIRCwswgHqKD5Pp/preview
var data = "?db="+ $rootScope.globals.currentUser.agents[$rootScope.globals.currentDB].db_name;
var url = apiserv+"api.properties.test.php"+data;
vm.dtOptions = DTOptionsBuilder.fromSource(url)
.withBootstrap()
// Active Buttons extension
.withButtons([
//'columnsToggle',
'colvis',
'copy',
'print',
'excel'
])
.withOption('fnRowCallback',myCallback)
.withOption('order', [[ 3, "desc" ]])
.withOption('stateSave',true);
vm.dtColumns = [
DTColumnBuilder.newColumn('File_Num').withTitle('File'),
DTColumnBuilder.newColumn('Description').withTitle('Description'),
DTColumnBuilder.newColumn('street').withTitle('Street'),
DTColumnBuilder.newColumn('bedrooms').withTitle('Bed'),
DTColumnBuilder.newColumn('bathrooms').withTitle('Bath'),
DTColumnBuilder.newColumn('garages').withTitle('Garages'),
DTColumnBuilder.newColumn('car_port').withTitle('Car Ports').notVisible(),
DTColumnBuilder.newColumn('Current_Monthly_Rental').withTitle('Rental').renderWith(function(data, type, full) {
return $filter('currency')(data, 'R ', 2); //could use currency/date or any angular filter
})
];
})
.controller('PagesListCtrl', function($scope,$rootScope,$http, DTOptionsBuilder, DTColumnBuilder, apiserv, $filter, $mdDialog, $mdMedia){
$scope.page = {
title: 'Dashboard',
subtitle: 'Place subtitle here...'
};
});
function myCallback(nRow, aData, iDisplayIndex, iDisplayIndexFull) {
$('td', nRow).bind('click', function() {
//$scope.$apply(function() {
showTabDialog(aData);
//});
});
return nRow;
};
function showTabDialog(ev) {
console.log(ev.file_id);
var data = "?db="+ $rootScope.globals.currentUser.agents[$rootScope.globals.currentDB].db_name+"&file="+ev.file_id;
var url = apiserv+"api.properties.view.php"+data;
console.log(url);
$http({url:url}).then(function(rs){
console.log(rs.data[0]);
$scope.propdata=rs.data[0];
$mdDialog.show({
controller: DialogController,
templateUrl: 'pages/properties/tabDialog.tmpl.html',
//parent: angular.element(document.body),
targetEvent: ev,
//onComplete: afterShowAnimation,
//scope:$scope,
//preserveScope: true
locals: { propdata: $scope.propdata }
})
.then(function(propdata) {
console.log(propdata);
//$scope.$parent.propdata = propdata; // Still old data
//vm.sname = propdata.street;
});
}, function(rs){
console.log("error : "+rs.data+" status : "+rs.status);
});
};
function DialogController($scope, $mdDialog, propdata) {
$scope.propdata = propdata;
$scope.form_size = "form-group-sm";
$scope.font_size = "font-size-sm";
$scope.hide = function(ret) {
//$scope.$apply(); Throws an error
$mdDialog.hide(ret);
}
$scope.changesize = function() {
var fsize = $scope.form_size.split("-").pop(); // "form-group-xs";
switch(fsize) {
case "sm" : fsize = "md";
break;
case "md" : fsize = "lg";
break;
case "lg" : fsize = "sm";
break;
}
$scope.form_size = "form-group-" + fsize;
$scope.font_size = "font-size-" + fsize;
}
}
This is how I had it and it worked, but as you can see the dialog is nested inside the controller and only usefull to that controller:
app
.controller('PropertiesCtrl', function($scope,$rootScope,$http, DTOptionsBuilder, DTColumnBuilder, apiserv, $filter, $mdDialog, $mdMedia){
$scope.page = {
title: 'Dashboard',
subtitle: 'Place subtitle here...'
};
$scope.getProperties = function(){
$scope.data=[];
//var url = 'http://www.filltext.com/?rows=10&fname={firstName}&lname={lastName}&delay=3&callback=JSON_CALLBACK';
var data = "?db="+ $rootScope.globals.currentUser.agents[$rootScope.globals.currentDB].db_name;
var url = apiserv+"api.properties.test.php"+data;
$http.jsonp(url).success(function(data){
$scope.data=data;
});
};
var vm = this;
function stateChange(iColumn, bVisible) {
console.log('The column', iColumn, ' has changed its status to', bVisible);
}
// TO-DO: Rather load from a Factory promise, like here: https://github.com/l-lin/angular-datatables/issues/14
// Example here: http://embed.plnkr.co/B9ltNzIRCwswgHqKD5Pp/preview
var data = "?db="+ $rootScope.globals.currentUser.agents[$rootScope.globals.currentDB].db_name;
var url = apiserv+"api.properties.test.php"+data;
vm.dtOptions = DTOptionsBuilder.fromSource(url)
.withBootstrap()
// Active Buttons extension
.withButtons([
//'columnsToggle',
'colvis',
'copy',
'print',
'excel'
])
.withOption('fnRowCallback',$scope.myCallback)
.withOption('order', [[ 3, "desc" ]])
.withOption('stateSave',true);
vm.dtColumns = [
DTColumnBuilder.newColumn('File_Num').withTitle('File'),
DTColumnBuilder.newColumn('Description').withTitle('Description'),
DTColumnBuilder.newColumn('street').withTitle('Street'),
DTColumnBuilder.newColumn('bedrooms').withTitle('Bed'),
DTColumnBuilder.newColumn('bathrooms').withTitle('Bath'),
DTColumnBuilder.newColumn('garages').withTitle('Garages'),
DTColumnBuilder.newColumn('car_port').withTitle('Car Ports').notVisible(),
DTColumnBuilder.newColumn('Current_Monthly_Rental').withTitle('Rental').renderWith(function(data, type, full) {
return $filter('currency')(data, 'R ', 2); //could use currency/date or any angular filter
})
/*DTColumnBuilder.newColumn('file_id').withTitle('').withClass('dt-right').renderWith(function(data, type, full) {
//return "<a href='#/app/statement/"+full.id+"' class='btn btn-default'>View</a>";
return "<a class=\"btn btn-default\" onclick='$(\"#myview\").click()'>View</a>";
}).notSortable()*/
];
$scope.showTabDialog = function(ev) {
console.log(ev.file_id);
var data = "?db="+ $rootScope.globals.currentUser.agents[$rootScope.globals.currentDB].db_name+"&file="+ev.file_id;
var url = apiserv+"api.properties.view.php"+data;
console.log(url);
$http({url:url}).then(function(rs){
console.log(rs.data[0]);
$scope.propdata=rs.data[0];
$mdDialog.show({
controller: DialogController,
templateUrl: 'pages/properties/tabDialog.tmpl.html',
//parent: angular.element(document.body),
targetEvent: ev,
//onComplete: afterShowAnimation,
//scope:$scope,
//preserveScope: true
locals: { propdata: $scope.propdata }
})
.then(function(propdata) {
console.log(propdata);
//$scope.$parent.propdata = propdata; // Still old data
//vm.sname = propdata.street;
});
}, function(rs){
console.log("error : "+rs.data+" status : "+rs.status);
});
};
function DialogController($scope, $mdDialog, propdata) {
$scope.propdata = propdata;
$scope.form_size = "form-group-sm";
$scope.font_size = "font-size-sm";
$scope.hide = function(ret) {
//$scope.$apply(); Throws an error
$mdDialog.hide(ret);
}
$scope.changesize = function() {
var fsize = $scope.form_size.split("-").pop(); // "form-group-xs";
switch(fsize) {
case "sm" : fsize = "md";
break;
case "md" : fsize = "lg";
break;
case "lg" : fsize = "sm";
break;
}
$scope.form_size = "form-group-" + fsize;
$scope.font_size = "font-size-" + fsize;
}
}
$scope.myCallback = function(nRow, aData, iDisplayIndex, iDisplayIndexFull) {
$('td', nRow).bind('click', function() {
$scope.$apply(function() {
$scope.showTabDialog(aData);
});
});
return nRow;
};
});
Here is factory to store and retrieve user from any controller:
app.factory('Auth', [, function () {
function getUser() {
return user;
}
var currentUser = getUser();
return {
currentUser: currentUser
}]);
And use it:
app.controller('controller', ['Auth', function(Auth) {
var currentUser = Auth.currentUser;
}]);
And don't forget to include new factory on page before controller.

Second jsonp http get request - using $q gives 404 error despite GET showing 200

I've found a couple of similar posts to this, but the answers (which boil down to putting callback=JSONP_CALLBACK into the get request) aren't working for me. Using that in the request generates an immediate 404 error, while using callback=angular.callbacks._0 at least lets the first request return a successful response. The problem is that using the very same request function with the very same params a second time to refresh the data or get the next 20 objects, returns a 404 error even though the actual get returns a 200 and the data can be seen in chrome tools.
I'm, new to using $q deferred promises, so I'm hoping that the issue has something to do with that not allowing enough time for a response before executing the reject. I'm attaching the code, which involves the Yelp API as did the other couple of posts I found on this issue. The most closely related is: (Subsequent JSONP requests give status 404 despite GET status 200), but there's another which uses the same callback string I'm using (Yelp API and AngularJS).
This particular project is for an ionic mobile app that gets coffee shops based on users geolocation.
Here's the code for the service (secret stuff removed):
var app = angular.module('caffeine.services', []);
app.service("YelpService", function ($q, $http, $cordovaGeolocation, $ionicPopup) {
function randomString(length, chars) {
var result = '';
for (var i = length; i > 0; --i) result += chars[Math.round(Math.random() * (chars.length - 1))];
return result;
};
var method = 'GET';
var url = 'http://api.yelp.com/v2/search';
var consumerSecret = ''; //Consumer Secret
var tokenSecret = ''; //Token Secret
var self = {
'page': 1,
'isLoading': false,
'hasMore': true,
'results': [],
'ranStr': randomString(32, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'),
'timeStamp':new Date().getTime(),
'lat': 51.544440,
'lon': -0.022974,
'term': 'coffee',
'oauthConKey': '', //Consumer Key
'oauthToken': '', //Token
'oauthSigMeth': 'HMAC-SHA1',
'refresh': function () {
self.page = 1;
self.isLoading = false;
self.hasMore = true;
self.results = [];
return self.load();
},
'next': function () {
self.page += 1;
return self.load();
},
'load': function () {
self.isLoading = true;
var deferred = $q.defer();
ionic.Platform.ready(function() {
$cordovaGeolocation
.getCurrentPosition({timeout:10000, enableHighAccuracy:false})
.then(function(position){
self.lat = position.coords.latitude;
self.lon = position.coords.longitude;
console.log('latlong = '+self.lat+','+self.lon);
var params = {
callback: 'angular.callbacks._0',
page: self.page,
ll: self.lat+','+self.lon,
term: self.term,
oauth_consumer_key: self.oauthConKey, //Consumer Key
oauth_token: self.oauthToken, //Token
oauth_signature_method: self.oauthSigMeth,
oauth_timestamp: self.timeStamp,
//new Date().getTime(),
oauth_nonce: self.ranStr
};
var signature = oauthSignature.generate(method, url, params, consumerSecret, tokenSecret, { encodeSignature: false});
params['oauth_signature'] = signature;
console.log('url ='+url);
console.log('params.ll = '+params.ll);
$http.jsonp(url, {params: params}).success(function (callback) {
self.isLoading = false;
console.log(callback.businesses);
if (callback.businesses.length == 0) {
self.hasMore = false;
} else {
angular.forEach(callback.businesses, function (business) {
self.results.push(business);
});
}
self.isLoading = false;
deferred.resolve(callback.businesses);
})
.error( function (callback, status, headers, config) {
self.isLoading = false;
console.error('data not received');
console.error('data: '+callback);
console.error('status: '+status);
console.error('headers: '+headers);
console.error('congig: '+config);
deferred.reject(callback);
});
}, function(err) {
console.error('Error getting position');
console.error(err);
$ionicPopup.alert({
'title': 'Please turn on geolocation',
'template': 'It looks like you have geolocation turned off. Please turn on geolocation in your app settings to use this app.'
});
})
});
return deferred.promise;
}
};
self.load();
return self;
});

angular, try to display object in ng-repeat fails

i'm writing an mobile application in javascript with angularJS and ionicframework (last beta v.11), i create dinamically an object and want to display all objects inside in a ng-repeat. Why nr-repeat don't display anything?
This is screen from my object:
I use this code for put values in scope:
$scope.distanceSuppliers = myCar;
And this is the code in html:
<ion-item ng-repeat="(id, supplier) in distanceSuppliers">
<div class="items item-button-right" ng-click="openDetails(id)">
{{supplier.name}}<br />
{{supplier.address}}<br />
</div>
</ion-item>
This is my complete code for JS:
.controller('suppliers', function($scope, cw_db, $ionicPopup, $ionicActionSheet, appdelegate, $rootScope, $firebase, $location, $ionicLoading, cw_position) {
$ionicLoading.show({
template: 'Updating data..'
});
var geocoder;
var tot = 0;
var done = 0;
geocoder = new google.maps.Geocoder();
cw_db.getData(cw_db.getSuppliers(), "", function(suppliers) {
cw_position.getPosition(function (error, position) {
suppliers.on('value', function(supp) {
$scope.distanceSuppliers = {};
tot = 0;
done = 0;
supp.forEach(function(childSnapshot) {
tot++;
var childData = childSnapshot.val();
if (childData.address) {
calculateDistance(childData, position.coords.latitude, position.coords.longitude);
}
});
});
$ionicLoading.hide();
});
});
function calculateDistance(childData, usrLat, usrLon) {
var service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix(
{
origins: [new google.maps.LatLng(usrLat, usrLon)],
destinations: [childData.address],
travelMode: google.maps.TravelMode.DRIVING,
unitSystem: google.maps.UnitSystem.METRIC,
avoidHighways: false,
avoidTolls: false
}, function(response, status) {
if (status != google.maps.DistanceMatrixStatus.OK) {
alert('Error was: ' + status);
} else {
done++;
var results = response.rows[0].elements;
childData.distance = results[0].distance.value;
$scope.distanceSuppliers.push(childData);
if (done == tot) {
console.log($scope.distanceSuppliers);
}
}
});
}
$scope.openDetails = function(index) {
//appdelegate.setCallId(index);
//$location.path("/app/supplierDetails");
}
})
what's wrong?
Not sure, but I believe you have a data binding update problem.
Try using the $timeout to force the render:
w_position.getPosition(function (error, position) {
$timeout(function() {
suppliers.on('value', function(supp) {
$scope.distanceSuppliers = {};
tot = 0;
done = 0;
supp.forEach(function(childSnapshot) {
tot++;
var childData = childSnapshot.val();
if (childData.address) {
calculateDistance(childData, position.coords.latitude, position.coords.longitude);
}
});
});
$ionicLoading.hide();
});
});
And don't forget to add the $timeout parameter to the controller:
.controller('suppliers', function($scope, ...<other parameters here>..., $timeout) {
I found the problem! Fix using $scope.$apply();
The problem was that i was writing in a different $scope using this code:
cw_position.getPosition(function (error, position) {
suppliers.on('value', function(supp) {
tot = 0;
done = 0;
supp.forEach(function(childSnapshot) {
tot++;
var childData = childSnapshot.val();
if (childData.address) {
calculateDistance(childData, position.coords.latitude, position.coords.longitude);
}
});
});
$ionicLoading.hide();
});
where cw_position.getPosition call a js with this code:
angular.module('cw_position', [])
.service('cw_position', function() {
this.getPosition = function(callback) {
navigator.geolocation.getCurrentPosition(
function (position) {
return callback(null, position);
},
function(error) {
return callback(error, null);
}
);
}
// Built google maps map option
//
this.getGoogleMapOptions = function (lat, lon, zoom, type) {
if (type == null) {
type = google.maps.MapTypeId.ROADMAP;
}
var mapOptions = {
center: new google.maps.LatLng(lat, lon),
zoom: zoom,
mapTypeId: type
};
return mapOptions;
}
});
navigator.geolocation.getCurrentPosition causes the 'problem'
Thx to all for your help

Resources