Promise into Promise

Is it ok to bundle Promise into Promise? In my app, i have DBService, which works with Sqlite plugin, saves and gets data from Db. DbService is inserted into ShiftService, which use dbService to get data, process them and then returns them. Final page uses ShiftService to get/store data. So function from DbService returns Promise, that uses function in ShiftService, that returns Promise too. Is it ok from design view? Or this should be solved another way?

What you mean by “bundle into” isn’t clear. Posting actual code would probably be the best way to solicit useful advice.

Ok, so in Database provider i got this method:

getShiftsFromShifts(){
    return new Promise(resolve=>{
      var shiftsString;
      this.storage.executeSql('SELECT * FROM shifts',{}).then((data)=>{
        console.log(data);
        if(data.rows.length>0){
          shiftsString=data.rows.item(0);
        }
        resolve(shiftsString);
      },(error)=>{
        console.log(error);
      });
    });
  }

Then i have ShiftService provider, Database service is injected into it.

public getShiftsFromDb(){
    return new Promise((resolve)=>{
      this.db.ready.then(()=>{
        this.db.getShiftsFromShifts().then((data:any)=>{
        console.log(data.shifts);
        resolve(JSON.parse(data.shifts));
        })
      });

    });
  }

ShiftService is then injected into HomePage. which uses it to load initial data.

this.platform.ready().then(()=>{
      this.shiftService.getShiftsFromDb().then((data)=>{
        this.shiftsArray=data;
        console.log('nacteny data');
        console.log(this.shiftsArray);
      })

Virtually any time you type new Promise() it’s a bad idea. There are great ways for you to do what you’re attempting simply by returning Promise chains, such as:

getShiftsFromDb(): Promise<Shift[]> {
  return this.db.ready() 
  .then(() => this.db.getShiftsFromShifts());
}
1 Like

so in the solution u are posting i just changed the getShiftsFromDb function and rest stays the same? And if i do it like this, what about the parse to JSON? ill have to do it on Page?

I suppose that’s a matter of opinion, but mine is strongly that all JSON parsing must be done in service providers, not in pages.

yea in my opinion JSON parsing belongs to service, but how can i done it, if i return chain of Promises…

And one more question , what about getShiftsFromShifts method? How do i change it to be more viable?

it would really help me out.

I’m confused, because you keep using plurals and * and talking about arrays, but your getShiftsFromShifts() method seems to simply return only the first element of the first row.

Yea sry, maybe i named it a little bit inapropriate. Iam getting only the first element, but this element is string, which can be parsed to array of objects- shifts.

I think you’re overengineering this. You’re only selecting one field from shifts, so name it instead of using *, and you should be able to just do this:

getFirstShiftName(): Promise<string> {
  return this.storage.ready()
    .then(() => this.storage.executeSql('SELECT name FROM shifts'))
    .then((shifts) => shifts.rows.length > 0 ? shifts.rows.item(0) : undefined);
}

Hi, i reworked my app with your advices in mind, with promises chaining, but i have a few issues.

This is my database provider.

export class Database {
  private dbName:string="shift.db";
  public storage:any;
  ready:Promise<void>;

  constructor(public http: Http, private sqlite:SQLite,private platform:Platform) {
    this.platform.ready().then(()=>{
      this.createDatabase();
    });
  }

  createDatabase(){
    this.ready=this.sqlite.create({
      name:this.dbName,
      location:'default'
    }).then((db:SQLiteObject)=>{
        this.storage=db;
        console.log("database ready");
        this.createTables();
      },
      (err)=>{
        console.error('Unable to open database');
      });
  }

  getShiftsFromShifts():Promise<string>{
    let shiftsString;
    return this.storage.executeSql('SELECT * FROM shifts',{}).then((data)=>{
        data.rows.length>0?data.rows.item(0):'testik';
      },(error)=>{
        console.log(error);
      });
  }

and this is method in shiftServiceprovider, which uses it.

  public getShiftsFromDb():Promise<Array<any>>{
    return this.db.ready.then(()=>{
      this.db.getShiftsFromShifts().then((shiftsString)=>{
        return JSON.parse(shiftsString);
      });
    });
  };

problem is, that it gives me error, that “type promise is not assignable to type promise<any[]>”, am i missing something? How can getShiftsFromDb method return void? Maybe i dont really understand promise chaining and i made some mistake. Any ideas? It only works if i do something like this

  public getShiftsFromDb():Promise<Array<any>>{
    return this.db.ready.then(()=>{
      return this.db.getShiftsFromShifts().then((shiftsString)=>{
        return JSON.parse(shiftsString);
      });
    });
  };

but this feels kinda weird. And how should the method in Homepage(method that uses method in shiftService) looks like, when i chain promises like this?