Onsenui with Bluetooth plugin - angularjs

I am trying to implement a bluetooth plugin using Onsenui in Monaca IDE. I keep getting an error message saying: bluetoothSerial not found.
I want to create a service that requires the Bluetooth Serial plugin. Then simply call this to do a .isenabled() call. Any help would be great.
app.service('iBeaconService', function() {
var bluetoothSerial = new cordova.plugins.bluetoothSerial;
return {
sendMessage: function(message) {
// interact with bluetoothSerial
}
};
});
app.controller('InfoPageCtrl', ['$scope', 'iBeaconService', function($scope, iBeaconService) {
bluetoothSerial.isEnabled(
function() {
console.log("Bluetooth is enabled");
},
function() {
console.log("Bluetooth is *not* enabled");
}
);
}]);
app.controller('AppController', function($scope) {
$scope.load = function(page) {
$scope.mySplitterContent.load(page)
}
$scope.open = function() {
$scope.mySplitterSide.open();
}
});
<ons-list ng-controller="InfoPageCtrl">
<ons-list-item class="list-item-container" >
<ons-row>
<ons-col width="110px">
<img src="{{beacon.icon}}" class="info-page-img">
</ons-col>
<ons-col>
<div class="info-page-description">
<p style="text-decoration: underline;">UUID</p>
{{beaconUuid}}
</div>
</ons-col>
</ons-row>
</ons-list-item>
</ons-list>

How to turn this code to use for Onsenui.
var app = {
initialize: function() {
this.bindEvents();
this.showMainPage();
},
bindEvents: function() {
var TOUCH_START = 'touchstart';
if (window.navigator.msPointerEnabled) { // windows phone
TOUCH_START = 'MSPointerDown';
}
document.addEventListener('deviceready', this.onDeviceReady, false);
refreshButton.addEventListener(TOUCH_START, this.refreshDeviceList, false);
sendButton.addEventListener(TOUCH_START, this.sendData, false);
disconnectButton.addEventListener(TOUCH_START, this.disconnect, false);
deviceList.addEventListener('touchstart', this.connect, false);
},
onDeviceReady: function() {
app.refreshDeviceList();
},
refreshDeviceList: function() {
bluetoothSerial.list(app.onDeviceList, app.onError);
},
onDeviceList: function(devices) {
var option;
// remove existing devices
deviceList.innerHTML = "";
app.setStatus("");
devices.forEach(function(device) {
var listItem = document.createElement('li'),
html = '<b>' + device.name + '</b><br/>' + device.id;
listItem.innerHTML = html;
if (cordova.platformId === 'windowsphone') {
// This is a temporary hack until I get the list tap working
var button = document.createElement('button');
button.innerHTML = "Connect";
button.addEventListener('click', app.connect, false);
button.dataset = {};
button.dataset.deviceId = device.id;
listItem.appendChild(button);
} else {
listItem.dataset.deviceId = device.id;
}
deviceList.appendChild(listItem);
});
if (devices.length === 0) {
option = document.createElement('option');
option.innerHTML = "No Bluetooth Devices";
deviceList.appendChild(option);
if (cordova.platformId === "ios") { // BLE
app.setStatus("No Bluetooth Peripherals Discovered.");
} else { // Android or Windows Phone
app.setStatus("Please Pair a Bluetooth Device.");
}
} else {
app.setStatus("Found " + devices.length + " device" + (devices.length === 1 ? "." : "s."));
}
},
connect: function(e) {
var onConnect = function() {
// subscribe for incoming data
bluetoothSerial.subscribe('\n', app.onData, app.onError);
resultDiv.innerHTML = "";
app.setStatus("Connected");
app.showDetailPage();
};
var deviceId = e.target.dataset.deviceId;
if (!deviceId) { // try the parent
deviceId = e.target.parentNode.dataset.deviceId;
}
bluetoothSerial.connect(deviceId, onConnect, app.onError);
},
onData: function(data) { // data received from Arduino
console.log(data);
resultDiv.innerHTML = resultDiv.innerHTML + "Received: " + data + "<br/>";
resultDiv.scrollTop = resultDiv.scrollHeight;
},
sendData: function(event) { // send data to Arduino
var success = function() {
console.log("success");
resultDiv.innerHTML = resultDiv.innerHTML + "Sent: " + messageInput.value + "<br/>";
resultDiv.scrollTop = resultDiv.scrollHeight;
};
var failure = function() {
alert("Failed writing data to Bluetooth peripheral");
};
var data = messageInput.value;
bluetoothSerial.write(data, success, failure);
},
disconnect: function(event) {
bluetoothSerial.disconnect(app.showMainPage, app.onError);
},
showMainPage: function() {
mainPage.style.display = "";
detailPage.style.display = "none";
},
showDetailPage: function() {
mainPage.style.display = "none";
detailPage.style.display = "";
},
setStatus: function(message) {
console.log(message);
window.clearTimeout(app.statusTimeout);
statusDiv.innerHTML = message;
statusDiv.className = 'fadein';
// automatically clear the status with a timer
app.statusTimeout = setTimeout(function () {
statusDiv.className = 'fadeout';
}, 5000);
},
onError: function(reason) {
alert("ERROR: " + reason); // real apps should use notification.alert
}
};

After installing the plugin with Monaca IDE and doing the custom Android build, I was able to get it to work using the following code:
ons.ready(function(){
bluetoothSerial.isConnected(
function() {
alert("Bluetooth is connected");
},
function() {
alert("Bluetooth is not connected");
}
);
});
The big thing to note, is you need to check for ons.ready, then access your variable.

Related

WebRTC remote video stream not working despite having src

I'm trying to make a simple AngularJS WebRTC video chat app based on this tutorial.
I'm able to connect to connect clients, add streams and play my own stream, but somehow I can't play the remote stream.
When I check the elements I can see that the videoplayer does in fact have a blob source, but it won't play it.
Can anyone tell me why it won't show?
HTML element:
Room controller:
angular.module('publicApp').controller('RoomCtrl', function ($sce, VideoStream, $location, $routeParams, $scope, Room)
{
if (!window.RTCPeerConnection || !navigator.getUserMedia) {
$scope.error = 'WebRTC is not supported by your browser. You can try the app with Chrome and Firefox.';
return;
}
var stream;
VideoStream.get()
.then(function (s) {
stream = s;
Room.init(stream);
stream = URL.createObjectURL(stream);
if (!$routeParams.roomId) {
Room.createRoom()
.then(function (roomId) {
$location.path('/room/' + roomId);
});
} else {
Room.joinRoom($routeParams.roomId);
}
}, function () {
$scope.error = 'No audio/video permissions. Please refresh your browser and allow the audio/video capturing.';
});
$scope.peers = [];
Room.on('peer.stream', function (peer) {
console.log('Client connected, adding new stream');
$scope.peers.push({
id: peer.id,
stream: URL.createObjectURL(peer.stream)
});
console.log($scope.peers);
});
Room.on('peer.disconnected', function (peer) {
console.log('Client disconnected, removing stream');
$scope.peers = $scope.peers.filter(function (p) {
return p.id !== peer.id;
});
});
$scope.getLocalVideo = function () {
return $sce.trustAsResourceUrl(stream);
};
});
Room factory:
angular.module('publicApp').factory('Room', function ($rootScope, $q, Io, config)
{
var iceConfig = { 'iceServers': [{ 'url': 'stun:stun.l.google.com:19302' }]},
peerConnections = {},
currentId, roomId,
stream;
function getPeerConnection(id)
{
if (peerConnections[id]) {
return peerConnections[id];
}
var pc = new RTCPeerConnection(iceConfig);
peerConnections[id] = pc;
pc.addStream(stream);
pc.onicecandidate = function (evnt) {
socket.emit('msg', { by: currentId, to: id, ice: evnt.candidate, type: 'ice' });
};
pc.onaddstream = function (evnt) {
console.log('Received new stream');
api.trigger('peer.stream', [{
id: id,
stream: evnt.stream
}]);
if (!$rootScope.$$digest) {
$rootScope.$apply();
}
};
return pc;
}
function makeOffer(id)
{
var pc = getPeerConnection(id);
pc.createOffer(function (sdp) {
pc.setLocalDescription(sdp);
console.log('Creating an offer for', id);
socket.emit('msg', { by: currentId, to: id, sdp: sdp, type: 'sdp-offer' });
}, function (e) {
console.log(e);
},
{ mandatory: { OfferToReceiveVideo: true, OfferToReceiveAudio: true }});
}
function handleMessage(data)
{
var pc = getPeerConnection(data.by);
switch (data.type) {
case 'sdp-offer':
pc.setRemoteDescription(new RTCSessionDescription(data.sdp), function () {
console.log('Setting remote description by offer');
pc.createAnswer(function (sdp) {
pc.setLocalDescription(sdp);
socket.emit('msg', { by: currentId, to: data.by, sdp: sdp, type: 'sdp-answer' });
});
});
break;
case 'sdp-answer':
pc.setRemoteDescription(new RTCSessionDescription(data.sdp), function () {
console.log('Setting remote description by answer');
}, function (e) {
console.error(e);
});
break;
case 'ice':
if (data.ice) {
console.log('Adding ice candidates');
pc.addIceCandidate(new RTCIceCandidate(data.ice));
}
break;
}
}
var socket = Io.connect(config.SIGNALIG_SERVER_URL),
connected = false;
function addHandlers(socket)
{
socket.on('peer.connected', function (params) {
makeOffer(params.id);
});
socket.on('peer.disconnected', function (data) {
api.trigger('peer.disconnected', [data]);
if (!$rootScope.$$digest) {
$rootScope.$apply();
}
});
socket.on('msg', function (data) {
handleMessage(data);
});
}
var api = {
joinRoom: function (r) {
if (!connected) {
socket.emit('init', { room: r }, function (roomid, id) {
currentId = id;
roomId = roomid;
});
connected = true;
}
},
createRoom: function () {
var d = $q.defer();
socket.emit('init', null, function (roomid, id) {
d.resolve(roomid);
roomId = roomid;
currentId = id;
connected = true;
});
return d.promise;
},
init: function (s) {
stream = s;
}
};
EventEmitter.call(api);
Object.setPrototypeOf(api, EventEmitter.prototype);
addHandlers(socket);
return api;
});
Directive:
angular.module('publicApp').directive('videoPlayer', function ($sce) {
return {
template: '<div><video ng-src="{{trustSrc()}}" autoplay></video></div>',
restrict: 'E',
replace: true,
scope: {
vidSrc: '#'
},
link: function (scope) {
console.log('Initializing video-player');
scope.trustSrc = function () {
if (!scope.vidSrc) {
console.log('No vidSrc found');
return undefined;
}
return $sce.trustAsResourceUrl(scope.vidSrc);
};
}
};
});
Room.html:
<div class="video-wrapper">
<video-player class="col-md-4" ng-repeat="peer in peers" vid-src="{{peer.stream}}"></video-player>
</div>
<div class="video-wrapper">
<div class="col-md-2">
<video ng-src="{{getLocalVideo()}}" autoplay muted></video>
</div>
</div>

call function synchronously inside an angular for each

I'm using ngCordova File Transfer plugin in an ionic project to download set of images from urls. Here is the code i'm using for that.
// Save a image file in a given directory
$scope.saveImage = function(dir,imgUrl,imageName) {
var url = imgUrl;
var targetPath = cordova.file.dataDirectory+ dir+"/" + imageName;
var trustHosts = true;
var options = {};
// Download the image using cordovafiletransfer plugin
$cordovaFileTransfer.download(url, targetPath, options, trustHosts)
.then(function(result) {
$scope.loadedCount ++;
$ionicLoading.show({template : "<ion-spinner class='spinner-energized'></ion-spinner><p> Downloading pages : "+ $scope.loadedCount+" of "+ $scope.pages.length+ "</p><p>Please wait...</p><p><button class=\"button button-block button-positive\">continue in background</button></p>"});
if($scope.loadedCount == $scope.pages.length) {
$ionicLoading.hide();
$scope.showDownloadSuccessAlert = function() {
var alertPopup = $ionicPopup.alert({
title: 'Success!',
template: "Your magazine successfully downloaded. You can view it on Downloads!"
});
};
$scope.showDownloadSuccessAlert();
}
}, function(err) {
alert(JSON.stringify(err));
}, function (progress) {
if($scope.loadedCount > 80) {
}
});
};
// Download the current magazine
$scope.downloadMagazine = function() {
if($rootScope.user.user_id == undefined) {
$scope.showLoginAlert = function() {
var alertPopup = $ionicPopup.alert({
title: 'Oops!',
template: "Your must login to download magazines"
});
};
$scope.showLoginAlert();
return;
}
document.addEventListener('deviceready', function () {
var dirName = $rootScope.currentIssue.slug+'_VOL_'+$rootScope.currentIssue.vol+'_ISU_'+$rootScope.currentIssue.issue;
// First create the directory
$cordovaFile.createDir(cordova.file.dataDirectory, dirName, false)
.then(function (success) {
var count = 1;
$scope.loadedCount = 0;
angular.forEach($scope.pages, function(value, key) {
var imgName = count+".png";
$scope.saveImage(dirName,value.link,imgName); // Then save images one by one to the created directory.
count++;
});
}, function (error) {
// Directory already exists means that the magazine is already downloaded.
$scope.showDownloadedAlert = function() {
var alertPopup = $ionicPopup.alert({
title: 'Why worry!',
template: "Your have already downloaded this magazine. You can view it on downloads"
});
};
$scope.showDownloadedAlert();
});
}, false);
};
})
Problem here is that program try to download everything at once without waiting for previous one to finish. How to wait for one file to finish downloading and then start the other?
Thanks
If you want to do that automatically (you're not the first one : How can I execute array of promises in sequential order?), you could try reducing the list of address to a single Promise that will do the whole chain.
$scope.pages.reduce(function (curr,next) {
return curr.then(function(){
return $scope.saveImage(dirName, curr.link, imgName);
});
}, Promise.resolve()).then(function(result) {
$ionicLoading.show({template : "<ion-spinner class='spinner-energized'></ion-spinner><p> Downloading pages : "+ $scope.loadedCount+" of "+ $scope.pages.length+ "</p><p>Please wait...</p><p><button class=\"button button-block button-positive\">continue in background</button></p>"});
if($scope.loadedCount == $scope.pages.length) {
$ionicLoading.hide();
$scope.showDownloadSuccessAlert = function() {
var alertPopup = $ionicPopup.alert({
title: 'Success!',
template: "Your magazine successfully downloaded. You can view it on Downloads!"
});
};
$scope.showDownloadSuccessAlert();
}
});
And don't forget to make your saveImage async which returns a promise.
UPDATE:
You will need to remove the then logic from your save method and return the download method call:
return $cordovaFileTransfer.download(url, targetPath, options, trustHosts).promise;
Then you can put your download handler into Promise.resolve()).then. See above.
There's no other way other than chaining your promises. Here's an example:
angular.module('app', [])
.service('fakeDownloadService', function($timeout) {
this.download = (file) => $timeout(() => file, 100);
return this;
})
.run(function($rootScope, $q, fakeDownloadService) {
var listOfFiles = [];
for (var i = 0; i < 10; i++)
listOfFiles.push('file' + i);
$rootScope.log = [];
$rootScope.download = () => {
listOfFiles
.reduce((prev, curr) => {
return prev.then((result) => {
if(result)
$rootScope.log.push(result + ' downloaded');
return fakeDownloadService.download(curr);
});
}, $q.resolve())
.then(() => $rootScope.log.push('all done'));
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.9/angular.min.js"></script>
<div ng-app="app">
<button ng-click="download()">Start</button>
<div>Log:</div>
<ul>
<li ng-repeat="entry in log track by $index">
{{entry}}
</li>
</ul>
</div>

Implementing similar functions in a function with (Input) Parameters?

I have the following function to launch Skype from my Ionic app:
myApp.controller("launchSkypeCtrl", function($scope, $ionicPopup, $cordovaInAppBrowser) {
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
$scope.launchSkype = function launchSkype() {
var scheme;
if (device.platform === 'iOS') {
scheme = 'skype://';
} else if (device.platform === 'Android') {
scheme = 'com.skype.raider';
} else if (device.platform === 'wp') {
scheme = 'skype:';
} else if (device.platform === 'windows8') {
scheme = 'skype:';
}
navigator.startApp.check(scheme, function(message) { /* success */
navigator.startApp.start(scheme, function(message) {
}, function(error) { /* error */
$ionicPopup.alert({
title: "Skype not startet!",
content: "Skype not startet!"
})
});
}, function(error) {
$ionicPopup.alert({
title: "Skype not installed",
content: "Skype not installed on this device. Please install it!"
})
});
}
}
});
I also have the similar function, which starts Google Hangouts:
myApp.controller("launchHangoutsCtrl", function($scope, $ionicPopup, $cordovaInAppBrowser) {
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
$scope.launchHangouts = function launchSkype() {
var scheme;
if (device.platform === 'iOS') {
scheme = 'gtalk://';
} else if (device.platform === 'Android') {
scheme = 'com.google.android.talk';
} else if (device.platform === 'wp') {
scheme = 'gtalk:';
} else if (device.platform === 'windows8') {
scheme = 'gtalk:';
}
navigator.startApp.check(scheme, function(message) { /* success */
navigator.startApp.start(scheme, function(message) {
}, function(error) { /* error */
$ionicPopup.alert({
title: "Google Hangouts not started!",
content: "Google Hangouts not started!"
})
});
}, function(error) {
$ionicPopup.alert({
title: "Google Hangouts not installed!",
content: "Google Hangouts not installed! Please install it!"
})
});
}
}
});
As can be seen, only the links of Apps are different. Otherwise everything is the same. Errors are of course linked with the app name. My question is how can I put these two same functions with different app links in a function? I have more then two functions. I will thus avoid the repetition of the same functions. How can I output the error messages of the respective apps in a single function? How would the function which includes the above features look like? How would the call of the start of the respective app look like?
You can pass the corresponding strings as a parameter. In this case an object:
function launchApp($ionicPopup, appConfig) {
var scheme;
if (device.platform === 'iOS') {
scheme = appConfig.iosScheme;
} else if (device.platform === 'Android') {
scheme = appConfig.androidScheme;
} else if (device.platform === 'wp') {
scheme = appConfig.wpScheme;
} else if (device.platform === 'windows8') {
scheme = appConfig.windows8Scheme;
}
navigator.startApp.check(scheme, function(message) { /* success */
navigator.startApp.start(scheme, function(message) {
}, function(error) { /* error */
$ionicPopup.alert({
title: appConfig.appName + " not started!",
content: appConfig.appName + " not started!"
})
});
}, function(error) {
$ionicPopup.alert({
title: appConfig.appName + " not installed!",
content: appConfig.appName + " not installed! Please install it!"
})
});
}
myApp.controller("launchSkypeCtrl", function($scope, $ionicPopup, $cordovaInAppBrowser) {
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
var skypeConfig = {
"appName": "Skype",
"iosScheme": "skype://",
"androidScheme": "com.skype.raider",
"wpScheme": "skype:",
"windows8Scheme": "skype:"
}
$scope.launchSkype = launchApp($ionicPopup, skypeConfig);
}
});
myApp.controller("launchHangoutsCtrl", function($scope, $ionicPopup, $cordovaInAppBrowser) {
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
var hangoutConfig = {
"appName": "Google Hangouts",
"iosScheme": "gtalk://",
"androidScheme": "com.google.android.talk:",
"wpScheme": "gtalk:",
"windows8Scheme": "gtalk:"
}
$scope.launchHangouts = launchApp($ionicPopup, hangoutConfig);
}
});
Where you define the objects is up to you.
Edit:
To get $scope.launchSykpe and $scope.launchHangouts to be functions instead of calls, use the below launchApp function:
function launchApp($ionicPopup, appConfig) {
return function() {
var scheme;
if (device.platform === 'iOS') {
scheme = appConfig.iosScheme;
} else if (device.platform === 'Android') {
scheme = appConfig.androidScheme;
} else if (device.platform === 'wp') {
scheme = appConfig.wpScheme;
} else if (device.platform === 'windows8') {
scheme = appConfig.windows8Scheme;
}
navigator.startApp.check(scheme, function(message) { /* success */
navigator.startApp.start(scheme, function(message) {
}, function(error) { /* error */
$ionicPopup.alert({
title: appConfig.appName + " not started!",
content: appConfig.appName + " not started!"
})
});
}, function(error) {
$ionicPopup.alert({
title: appConfig.appName + " not installed!",
content: appConfig.appName + " not installed! Please install it!"
})
});
};
}
I didn't test it, but it should work now as inteded.

Cordova/Ionic httpd server plugin - url not visible

i have a problem with Angular controller in my Ionic/Cordova project.
Can someone explain me why url which i get in line 25: $scope.serverURL=url;
isn't visible in line 63 alert($scope.serverURL); (it return null)?
Here is my controller:
var app = angular.module('iremotee');
app.controller('StreamingController', function(ConnectSdkService, $scope, $rootScope, $state, Camera) {
var options = {
quality: 100,
destinationType: 0,
sourceType: 0,
mediaType: 2
};
$scope.currentFile = null;
$scope.httpd = null;
$scope.serverURL = null;
alert($scope.serverURL + "!!!");
$scope.createHttpd = function() {
$scope.httpd = (cordova && cordova.plugins && cordova.plugins.CorHttpd) ? cordova.plugins.CorHttpd : null;
};
$scope.startMediaServer = function() {
if ($scope.httpd) {
// before start, check whether its up or not
$scope.httpd.getURL(function(url) {
if (url.length > 0) {
$scope.serverURL = url;
alert($scope.serverURL);
} else {
$scope.httpd.startServer({
'www_root': '/',
'port': 8080,
'localhost_only': false
}, function(url) {
$scope.serverURL = url;
alert($scope.serverURL);
}, function(error) {});
}
});
} else {}
};
$scope.stopServer = function() {
if ($scope.httpd) {
$scope.httpd.stopServer(function() {}, function(error) {});
}
};
$scope.getMedia = function() {
$state.go('mainmenu');
};
ionic.Platform.ready(function() {
$scope.createHttpd();
$scope.startMediaServer();
});
$scope.getFile = function() {
alert($scope.serverURL);
Camera.getFromMemory(options).then(function(URI) {
if (URI.indexOf("file://") == -1) {
URI = "file://" + URI;
}
window.resolveLocalFileSystemURL(URI, function(fileEntry) {
var URI = fileEntry.toURL();
var str = URI;
str = str.replace("file:///storage/emulated/0/", "/sdcard/");
str = str.replace("file:///storage/emulated/0/", "/sdcard1/");
str = str.replace("file:///storage", "");
Camera.currentURI = str;
alert(Camera.currentURI);
$scope.currentFile = Camera.currentURI;
}); //resolveLocalFileSystemURL-END
}, function(err) {
alert(err);
}); //getFromMemory-END
}; //getFile-END
$scope.$on('$destroy', function() {
$scope.stopServer();
});
});

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