2

I am trying to update local Storage with a function called addDevice(), it checks if there is already some data in a key then it appends to that else just update the key.

export class DeviceService implements devicesInterface {

  devices : Array<deviceInterface> = [];  

  constructor(private storage : Storage, private http : HttpClient) { }

    addDevice(ssid : String, name : String){
      console.log("add device called "+ssid +name)
      return this.getDevices().then((res : devicesInterface) => {
        console.log("res");
        console.log(res)
        if (res) {

          this.devices = res.devices;
          console.log(res);
          this.devices.push({ ssid: ssid, name: name });
          return this.storage.set(TOTAL_DEVICES, { devices: this.devices });
        }
        else {
          console.log("not res");
          let devices_obj = { devices: [{ ssid: ssid, name: name }] };
          return this.storage.set(TOTAL_DEVICES, devices_obj);
        }
      })     
  }


  getDevices(){
    return this.storage.get(TOTAL_DEVICES)
  }
}

And from the page, I'm calling an API which resolves in an array of type deviceInterface.

  this.deviceService.getDevicesFromServer(this.authenticationService.getToken())
        .subscribe((res : Array<deviceInterface>) =>{
            if(res){
              this.storage.remove("TOTAL_DEVICES")
              this.devices = []
            }

            res.map(async device => {
              await this.deviceService.addDevice(device.ssid, device.name).then(res=>{
                console.log("device added..")
                this.devices.push(device)
                console.log(res)
              })
            });
          })

addDevice function has to be called in the chain, so that when next time its called it gets the data and append it, if this function is called asynchronously then data will get over-written again and again.

I have searched a lot but didn't find any relevant solution that matches my problem, how do I chain the iteration on res object and call addDevice function after the last call is resolved.

Rishabh Gusain
  • 683
  • 1
  • 6
  • 23
  • Are you sure that your map function is doing what you think it is? Check out this answer https://stackoverflow.com/a/37576787/4553162 to see that you can't really do a loop like that and expect it to wait for each iteration to finish before it fires off teh next call to `addDevice` – mahi-man Mar 01 '19 at 07:03
  • a little code could be so much helpful, I don't think map should be used hear as an iterator. – Rishabh Gusain Mar 01 '19 at 07:09
  • sure, I'll add an example for what I am suggesting as a answer – mahi-man Mar 01 '19 at 07:12

2 Answers2

2

I don't think your map function is waiting for each iteration to finish so the results are being overwritten. Could you try:

for (const device of res) {
    await this.deviceService.addDevice(device.ssid, device.name)
    .then(res => {
            console.log("device added..")
            this.devices.push(device)
            console.log(res)
    })
}

For more details see https://stackoverflow.com/a/37576787/4553162

mahi-man
  • 4,326
  • 2
  • 25
  • 36
  • 1
    This worked, this is the right syntax to use await, before using map I tried for each with no luck. also aysnc has to be used right after .subscribe(async – Rishabh Gusain Mar 01 '19 at 07:24
0

You are returning wrong promise from addDevice() method. Return the setter promise rather than getter promise

addDevice(ssid : String, name : String){
  console.log("add device called "+ssid +name);

  return new Promise((resolve, reject) => {
    this.getDevices().then((res : devicesInterface) => {
      console.log("res");
      console.log(res);

      if (res) {
        this.devices = res.devices;
        console.log(res);
        this.devices.push({ ssid: ssid, name: name });
        this.storage.set(TOTAL_DEVICES, { devices: this.devices }).then(resolve).catch(reject);
      }
      else {
        console.log("not res");
        let devices_obj = { devices: [{ ssid: ssid, name: name }] };
        this.storage.set(TOTAL_DEVICES, devices_obj).then(resolve).catch(reject);
      }
    });
  });   

}

  • 1
    I updated addDevice method to return the setter promise as you have suggested, still the same problem loop runs so fast do not wait for the promise to resolve before running another promise and resulting in the execution of else case of addDevice everytime – Rishabh Gusain Mar 01 '19 at 06:58