2

wifiservice.js:

angular.module('app.WifiServices', [])
    .factory('WifiService', function(){
        var unique_array = angular.fromJson('[]');

        function win_wifi(e){
        alert("Success");
        }

        function fail_wifi(e){
        alert("Error");
        }

        function connectWifi(wifi_ssid){
          WifiWizard.connectNetwork(wifi_ssid, win_wifi, fail_wifi);
        }

        function listHandler(a){

      var network_array = [];
      for(var i=0; i<a.length; i++){
        network_array.push("SSID: " + a[i].SSID + " Signal: " + a[i].level);
      }

      unique_array = network_array.filter(function(elem, pos) {
        return network_array.indexOf(elem) == pos;
      });

      // alert("Wifi List Ready!");
    }

    function getScanResult(){
      WifiWizard.getScanResults(listHandler, failNetwork);
    }

    function successNetwork(e){
      window.setTimeout(function(){
        getScanResult();
      }, 3000);
    }

    function failNetwork(e){
      alert("Network Failure: " + e);
    }

    window.setTimeout(function(){
      WifiWizard.startScan(successNetwork, failNetwork);
    }, 1000);

        return {
          list: function(){
            return unique_array;
          },

          connectionToWifi: function(name){
            connectWifi(name);
          }
        };
    });

My whole controller:

app.controller('WifiController', ['$scope', 'WifiService', function($scope, WifiService) {

 $scope.wifiList = [];

 window.setTimeout(function() {
  $scope.wifiList = WifiService.list();
  // alert($scope.wifiList);
  $scope.$apply();
 }, 5000);

 $scope.getList = function() {
  $scope.wifiList = WifiService.list();
  return $scope.wifiList;
 }

 $scope.connectWifi = function(name) {
  WifiService.connectionToWifi(name);
 }

 $scope.checkin = function() {
  $scope.getList()
  .then(function(result) {
     console.log(result);
 });
}

}]);

What I am trying to do is, to call the $scope.getList(), which returns a list of the surrounding wifi SSIDs, then within $scope.checkin() I would like to process those data.

Since scanning needs some time I have to wait the getList function to finish, thats Why I am trying to use .then, but it gives me the error says on the title. Any ideas?

georgeawg
  • 48,608
  • 13
  • 72
  • 95
Bobys
  • 677
  • 1
  • 14
  • 37
  • 1
    You need to return something that has a promise ! An Alternative use `.success` instead! – Tushar Gupta Mar 30 '17 at 15:18
  • @Tushar is right, but bear in mind that `.success` is deprecated! – lealceldeiro Mar 30 '17 at 15:21
  • Unless WifiService.list() has a blocking operation, there is no reason to use promises here. Can we see what this function looks like? – tier1 Mar 30 '17 at 15:23
  • @lealceldeiro correct , but it all depends on `WifiService.list()`. Dont see any point of promise until it is a http request – Tushar Gupta Mar 30 '17 at 15:25
  • Thanks for your time, I have added the wifiservice.js on the question – Bobys Mar 30 '17 at 15:27
  • you can do .$promise – yBrodsky Mar 30 '17 at 15:28
  • `list` should return a promise. And it doesn't return a promise. As it was said above. The suggestion is to move away from this setTimeout mess to promises. – Estus Flask Mar 30 '17 at 15:52
  • 1
    Looking at your code, I think this will help you give a better understanding: http://www.codingeek.com/angularjs/angular-js-apply-timeout-digest-evalasync/ It really helped me in understanding when to use (or not use) scope.apply(). – clever_bassi Mar 30 '17 at 16:02

2 Answers2

2

How to create a AngularJS promise from a callback-based API

To create an AngularJS promise from a callback-based API such as WifiWizard.connectNetwork, use $q.defer:

function connectWifi(wifi_ssid) {
   var future = $q.defer();
   var win_wifi = future.resolve;
   var fail_wifi = future.reject;
   WifiWizard.connectNetwork(wifi_ssid, win_wifi, fail_wifi);
   return future.promise;       
};

The above example returns a $q Service promise that either resolves or rejects using the callbacks from the API.

Community
  • 1
  • 1
georgeawg
  • 48,608
  • 13
  • 72
  • 95
0

Well, I came up with something different:

var unique_array = [];
  $scope.wifiList = [];
  $ionicLoading.show({
    template: "Scanning surrounding AP's..."
  });

 window.setTimeout(function() {
  $scope.wifiList = WifiService.list();
  // alert($scope.wifiList);
  while ($scope.wifiList == []) {
    console.log('Scanning...');
  }
  $scope.$apply();
  $ionicLoading.hide();
 }, 5000);

What I realize is that the scanning starts once I load the view. So, I added an IonicLoader to force the user to wait, and not be able to press any buttons till the scan is finished. So no function shall wait one another. Not quite code-wise correct, but it does what I need.

Bobys
  • 677
  • 1
  • 14
  • 37