Get data from service using SQLite plugin

Hello guys,

i’ve been trying to fetch some data from the SQLite database through the SQLite plugin ($ ionic cordova plugin add cordova-sqlite-storage /$ npm install --save @ionic-native/sqlite).

In my home.component.ts I did:

import { SQLite, SQLiteObject } from '@ionic-native/sqlite';

...
@Component({
  selector: 'page-home',
  templateUrl: 'home.html',
  providers:[recuperadorService, SQLite, databaseService]
})

...

  constructor(public http: Http, public navCtrl: NavController, public navParams: NavParams, private sqlite: SQLite, public bd: databaseService) {}

...

testselectsql(){
        this.message = this.bd.select();
}

and in my service I did:

import { Injectable } from '@angular/core';
import { SQLite, SQLiteObject } from '@ionic-native/sqlite';

@Injectable()
export class databaseService{
    db: Promise<any>;
    retorno: any;
    constructor( public sqlite: SQLite){
    }

    select(){
        this.open().then((teste) => {teste.executeSql("select * from danceMoves", {}).then((data) => {
                            for(var i =0; i< data.rows.length;i++){
                                this.retorno += data.rows.item(i).name;
                            }
                        } )});
        return this.retorno;
    }

    open(){
        return this.sqlite.create({name: 'data.db', location: 'default'});
    }

When i click on a button to call the “testselectsql()” function, nothing happens at first, butf i click on it the second time, I can get the result expected from the database.

The weird thing is, that when I put the logic of the service inside my home.component.ts, on the first click I can get the result expected.

What am I doing wrong?

Thank you

There are several problems here.

  • you are abusing any. provide proper types of all properties and return values of all methods
  • you are not following naming conventions. all classes should be PascalCase, not camelCase
  • 99% certain that you do not want to be declaring providers on components
  • it’s far from certain that you even want to be dealing with SQLite explicitly at all. ionic-storage is a much friendlier option
  • any attempt to interact with any plugins must be guarded in some fashion with Platform.ready().

Okay,

aside your personal comments, do you know how I can fetch the data without having to click twice?

Thanks

I find this attitude rather frustrating. I am trying to help you. Did you implement all that advice? If so, did you discover that maybe it fixed your problem?

  1. i’m using any because I don’t know how to do it any other way.
  2. corrected this issue
  3. angular page shows and example that instruct people to inject services into components
  4. I rather be using it like this
  5. I tried but no success.

The weird thing happens here inside my method select on the service:

this.open().then(
            (teste) => {teste.executeSql("select * from danceMoves", {}).then(
                    (data) => {
                            for(var i =0; i< data.rows.length;i++){
                                this.retorno += data.rows.item(i).name;
                            }
                    }
                )
            }
        );

on the first method call, everything inside “(teste) => {teste.executeSql(“select * from danceMoves”, {}).then(” it’s not returned. When I call this method again, it runs normally.

1 Like

Define an interface and use that.

When you do it this way, you get a separate instance per component. This is almost never what you want. Leave all providers in the app module.

Why? It makes development considerably more complicated.

Directly or indirectly, you must wrap absolutely everything that interacts with plugins inside Platform.ready().then().

If I call something other than the .executeSql, I can get the result on the first method call, like:

open(){
        return this.sqlite.create({name: 'data.db', location: 'default'});
    }

but when I call executeSql, even implementing what you said, no deal…

I solved the problem by doing this:

Inside the method on service:

return new Promise((resolve, reject) => {
            this.open().then(
                (teste) => {
                    teste.executeSql("select * from danceMoves", {}).then(
                        (data) => {
                            let retorno;
                                for(var i =0; i< data.rows.length;i++){
                                    retorno += data.rows.item(i).name;
                                }
                                resolve(retorno);
                        }
                    )
                }
            );
        });

Inside the component method:

this.bd.select().then((data) => this.aviso = data);

and it works :slight_smile:

You are instantiating an extra Promise for no reason.

return this.open()
  .then((teste) => teste.executeSql())
  .then((dbrv) => {
    // all the concatenation stuff
    return retorno;
  });

Except you code didn’t work for me :confused: