Timing problems with SQLite storage


#1

Hey Ionic community,
I’m trying to create a very simple app with Ionic that uses a JSON API. The idea is to save the API base url in the SQLite storage.
My code looks like this:

game-service.ts:

import {Injectable} from 'angular2/core';
import {Http, Headers} from 'angular2/http';
import {Game} from "../interfaces/game";
import {SqlStorage, Storage} from 'ionic-angular';



@Injectable()
export class GameService {
    private _storage: Storage;
    serverURL: String;
    constructor(private http: Http) {
        this._storage = new Storage(SqlStorage);
        this._storage.get("serverURL").then(
            data => this.serverURL = data
        );
    }
    getGames() {
        let games = this.http.get(this.serverURL + "/api.php?request=list");
        return games;
    }
    getDetails(game: Game){
        let id = game.id;
        console.log("getDetails mit " + this.serverURL);
        let detail = this.http.get(this.serverURL + '/api.php?request=detail&id=' + id);
        return detail;
    }
}

details.html:

<ion-navbar *navbar>
    <ion-title>
        {{ game.gameName }}
    </ion-title>
</ion-navbar>

<ion-content>
    <ion-list>
        <ion-item>
            Seller country
            <div item-right>{{gameDetails?.sellerCountry}}</div>
        </ion-item>
    </ion-list>
    <button block (click)="test()" outline default>Test</button>

</ion-content>

details.ts:

import {Page,NavController, NavParams} from 'ionic-angular';
import {OnInit} from 'angular2/core';
import {GameService} from "../../../services/game-service";
import {Game} from "../../../interfaces/game";
import {GameDetails} from "../../../interfaces/game-details";


@Page({
    templateUrl: 'build/pages/details/details.html',
    providers: [GameService]
})

export class DetailsPage implements OnInit{
    private game: Game;
    public gameDetails: GameDetails;
    constructor (private _gameservice: GameService, private _nav: NavController, private _navParams: NavParams){
        this.game = _navParams.get('game');
    }
    ngOnInit(){
        console.log(this._gameservice.serverURL);
        this._gameservice.getDetails(this.game).subscribe(
            data => this.gameDetails = data.json(),
            err => console.error(err),
            () => console.log('getDetails completed')
        );
    }

    test(){
        console.log(this._gameservice.serverURL);
    }
}

My problem:
When I navigate to the “Details” page of my app it’s not able to get data from the API and I get a Failed to load resource: the server responded with a status of 404 (Not Found) error message but when I press the “Test” button the correct server URL is printed in the console.
I assume that there is some kind of timing problem (maybe the page loads faster than the SQLite storage).

How can I fix my problem and use the URL from the SQLite storage for my API call?

Thanks in advance for the help :slight_smile:


#2

There are a number of ways to approach this. Probably the simplest would be to have getGames check to see if serverURL has been set, and return some sort of dummy (an empty array, for example) in the case that it has not been.


#3

Thanks you so much for your answer, I’m sure it would have solved my problem.
However yesterday I read an article about promises in Angular 2 and thought that this could also be an elegant solution for my problem and I could also learn something new and I tried to implement promises while using your idea with the dummy data. Of course this caused a new problem in my code.

My files (should have used Gists before, sorry for the spam :innocent:):

details.html

details.ts
game-service.ts
settings-service.ts

My problem:
The seller country on my details page doesn’t change when the data is received from the API server, it keep showing “Loading”. What confuses me is that it changes to “Loading 2” when I click the “Test” button. Also the console output seems to look fine:

[Log] getDetails: promise started (app.bundle.js, line 71227)
[Log] Promise in SettingsService started (app.bundle.js, line 71266)
[Log] Promise in SettingsService resolved, loaded from storage (app.bundle.js, line 71273)
[Log] getDetails: get data with http://some.url (app.bundle.js, line 71229)
[Log] ngOnInit started (app.bundle.js, line 69)
[Log] {sellerCountry: "United Kingdom"} (app.bundle.js, line 72)

What can I do to fix this (sorry if the mistake is stupid and sorry for making my problem more complex :innocent:)?


#4

TL;DR If you’re not using the latest Ionic 2 release I’ll suggest you to update to beta.6 as there were some bugs that caused problems with the view updates.


#5

Thanks a lot, this solved my issue.
However it get his error message in my browser console and the default view when executing ionic serve changed from iOS to Android: [Error] Failed to load resource: the server responded with a status of 404 (Not Found) (es6-shim.map, line 0)
Should I be worried? :innocent:


#6

It’s strange that it tries to load es6-shim.map - double-check that you’re not importing es6-shim somewhere, you should only have es6-shim.min.js in index.html.


#7

Ah, thanks, I found the problem: Insted of removing es6-shim from the app.ts I tried to comment it out (// import 'es6-shim';), which my IDE highlited correctly but apparently wasn’t enough.
ionic serve still shows the Android version of the app but I’m okay with that.


#8

I also wouldn’t have guessed that it will try to load the source-map when the import is commented out, it’s pretty strange. Thanks for the tip though! About the Android version - it’s the new default for desktop web.


#9

Ah, I see, thanks for clarifying. :thumbsup: