Plugins and Promises: how to manage responses


#1

Hi , I’m using plugins like Ionic Native File and Cordova Wifiwizard.

I have the following methods

  getmap() {
File.readAsText(this.storageDirectory + "/MyIonicApp", "mapa.txt").then((map) => {
  var array = [];
  var mapa1 = eval('(' + map + ')');
  for (var i in mapa1) {
    var AREA = mapa1[i]["AREA"];
    var BSSID = mapa1[i]["BSSID"];
    var AVG_RSSI = mapa1[i]["AVG_RSSI"];
    array.push({ AREA: AREA, BSSID: BSSID, AVG_RSSI: AVG_RSSI });
  }
  alert("Este é o mapa do telemóvel: " + JSON.stringify(array));
}, (err) => { alert("nao da para ler") });
  }

getallNetworks() {
WifiWizard.startScan(
  (data) => {
    WifiWizard.getScanResults(this.listHandler, (data) => { //alert(data) 
    })
  },
  (error) => {
  }
);
  }

listHandler(b = {}) {
  var array = [];
  for (var i in b) {
    var BSSID = b[i].BSSID;
    var level = b[i].level;
    array.push({ BSSID: BSSID, level: level });
  }
  alert("rastreio redes wifi " + JSON.stringify(array));
}

They work, I get the response I want, but I need to use that response (in both cases its the built array) outside this functions. I tried to atribute the respective value to a global var or pass them as parameter to another function and nothing, it’s like the value is stuck inside the function :confused: I will appretiate any help! :slight_smile:


#2

Hi. You have to return the array and also return the promise. Maybe try something like this:

getmap() {
  return File.readAsText(this.storageDirectory + "/MyIonicApp", "mapa.txt").then((myMap) => {
    let myArray = [];
    let mapa1 = eval('(' + myMap + ')');
    for (let i in mapa1) {
      let AREA = mapa1[i]["AREA"];
      let BSSID = mapa1[i]["BSSID"];
      let AVG_RSSI = mapa1[i]["AVG_RSSI"];
      myArray.push({ AREA: AREA, BSSID: BSSID, AVG_RSSI: AVG_RSSI });
    }
    return myArray;
  }).catch((err) => {
    console.log("nao da para ler")
  });
}

And when you want to use the array, do something like this:

this.getmap().then((myArray) => {
  // use myArray
});

#3

Thanks but for the then in this.getmap(), I get the error: Property ‘then’ does not exist on type ‘void’!


#4

Hmm… did you add the return before the File.readAsText()?


#5

Ok i forgot the that return :smirk:, thank you soooo much, your solution works !!! :smiley:


#6

But and now if I need to do the same with

getallNetworks() {
WifiWizard.startScan(
  (data) => {
    WifiWizard.getScanResults(this.listHandler, (data) => { //alert(data) 
    })
  },
  (error) => {
  }
);
  }

listHandler(b = {}) {
  var array = [];
  for (var i in b) {
    var BSSID = b[i].BSSID;
    var level = b[i].level;
    array.push({ BSSID: BSSID, level: level });
  }
  alert("rastreio redes wifi " + JSON.stringify(array));
}

the method WifiWizard.getScanResults retrieves a list of the available networks as an array of objects and passes them (obligatorily) to the function listHandler.

I want to use the array returned by the listHandler, i tried to do the same but it doesn’t work… Sorry, I know it’s my fault, I still do not understand how to work in the best way with promises!


#7

I’ll say up front that asynchronous programming has a bit of a learning curve. I’d recommend learning more about it first, both Promises and Callbacks. I’m no expert on WifiWizard, but I just read the docs. You don’t need to start a scan to get scan results from what I can tell in the docs, so I would start by removing that.

Secondly, WifiWizard does not use Promises at all, it uses callbacks. Before Promises were the standard callbacks were used for handling asynchronous actions. In this case listHandler is the callback function wifi wizard will pass the resulting list to.

If you want to keep using callbacks here instead of promises, then you just need to do whatever you want to with your array inside the listHandler function, or make getAllNetworks take in a callback like:

getAllNetworks(callback) {
  WifiWizard.getScanResults(callback);
}

Then outside that function you could do:

this.getAllNetworks(function (unformattedArray) {
  // format your array here and do something with it
}

BUT if it were me I’d convert this into a Promise syntax like so:

promisifiedGetScanResults() {
  return new Promise((resolve, reject) => {
    WifiWizard.getScanResults(resolve, reject);
  });
}

Now this call will return a promise containing the unformatted list of networks back from WifiWizard, which per the docs should look like this:

[
    {   "level": signal_level, // raw RSSI value
        "SSID": ssid, // SSID as string, with escaped double quotes: "\"ssid name\""
        "BSSID": bssid // MAC address of WiFi router as string
        "frequency": frequency of the access point channel in MHz
        "capabilities": capabilities // Describes the authentication, key management, and encryption schemes supported by the access point.
    }
]

If you want to format them with your listHandler, make sure your listHandler function returns the array after the loop (currently you just alert it, make it return array at the end). I’m a bit confused as to what that listHandler is doing to be honest, since getScanResults passes an array in not an object, but I’ll leave that piece alone for now and just say you can then do:

getAllNetworkds() {
  return promisifiedGetScanResults()
    .then(this.listHandler)
    .then(formattedArray => {
      // do whatever you want with the final array here
    });
}

#8

hey MASG do u have any idea how to use ngfor inside ion-input I have used but when I entered amount in input field then it will take the same amount in remaining field

<ion-card id=“maincard” padding *ngFor=“let item of bating;let i=index” [(ngModel)]=“selectedvalue” [hidden]=“maincard”>


<ion-input style=“width: 75px;” type=“number” id="{{i}}" placeholder=“1234{{i}}” [(ngModel)]=“bidAmount” class=“amount” clearInput required>

  </ion-col>
  <ion-col text-center>
    <button ion-button small outline  (click)="btn_betting_wetten(item.bet_id,item.topic_id,'bottom')" type="submit" disabled={{btnWetten}} > Wetten</button>
  </ion-col>

  <ion-col text-right style="margin-top: 5px;padding-right: 5px">
    <ion-label style="padding-right: 10px;">$ {{item.bet_amount}}  </ion-label>
  </ion-col>
</ion-row>

#9

Thank you so much, you saved my life, now I understand much better what I’m doing :slight_smile:


#10

sorry but noooooo :frowning:


#11

I am trying to do the same thing. I got the scan results in an alert function but now I want to bind it with the view. Can you please help me on this. Please share your working code.