Beginner’s quick Ionic app guide to service-driven offline cached global variables
Posted atMany guides are full with loads of extra information. I hope my direct guide gets you the information you need to build your awesome new app in Ionic.
ionic start myObservedApp
npm install --save @ionic/storage rxjs
Now we need to register the modules in our AppModule, eg. src/app/app.module.ts
//.........
import { HttpClientModule } from '@angular/common/http';
import { IonicStorageModule } from '@ionic/storage';
//.........
@NgModule({
declarations: [
...
],
imports: [
...
HttpClientModule, // We will use the HttpClient for our API provider
IonicStorageModule.forRoot(), // Add the storage module
IonicModule.forRoot(MyApp),
],
providers: [
...
],
//.........
})
export class AppModule {}
ionic g provider SharedData
ionic g provider PostPlaceholder
The ionic generate provider [name] command should have added these providers to src/app/app.module.ts. In case it did not, take a look at the snippet below.
//.........
import { SharedDataProvider } from '../providers/shared-data/shared-data';
import { PostPlaceholderProvider } from '../providers/post-placeholder/post-placeholder';
//.........
@NgModule({
...
providers: [
...
PostPlaceholderProvider,
SharedDataProvider,
...
],
//.........
})
export class AppModule {}
import { Injectable } from '@angular/core';
import { Subject, BehaviorSubject } from "rxjs/Rx";
import { Storage } from "@ionic/storage";
import { PostPlaceholderProvider } from '../post-placeholder/post-placeholder';
//.........
@Injectable()
export class SharedDataProvider {
...
// Initialize default BehaviorSubject
public post: Subject<object> = new BehaviorSubject<object>({});
...
constructor(
private _storage: Storage, // Use Storage for caching
private _postPlaceholderProvider: PostPlaceholderProvider, // Provider for communication with API
) {
this._storage.ready().then(() => {
// Get cached post from storage
this.post.next(post);
});
});
}
...
/*
Fetch new post and update storage
*/
fetchPost(postId: number) {
this._postPlaceholderProvider.getPost( postId ).subscribe((post: object) => {
this.post.next(post);
this._storage.set('post', post);
});
}
...
}
public events: Subject<Array< PostPlaceholder >> = new BehaviorSubject<Array< PostPlaceholder >>([]);
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import 'rxjs/add/operator/map'
//.........
// Interface for the data returned by the JSONPlaceholder API
export interface PostPlaceholder {
userId: number;
id: number;
title: string;
body: string;
}
//.........
@Injectable()
export class PostPlaceholderProvider {
// url for getting placeholder post
private readonly apiUrl: string = 'https://jsonplaceholder.typicode.com/posts/';
constructor(public _http: HttpClient) {
...
private _http: Http,
...
) {...}
...
/*
Return Promise for "https://jsonplaceholder.typicode.com/posts/postId"
*/
getPost(postId: number) {
return this._http.get(this.apiUrl + postId);
}
...
}
//.........
//.........
import { Component } from '@angular/core';
import { SharedDataProvider } from '../../providers/shared-data/shared-data';
import { PostPlaceholder } from '../../providers/post-placeholder/post-placeholder';
//.........
export class HomePage {
...
public post: PostPlaceholder;
...
constructor(
...
private _sharedData: SharedDataProvider,
...
) {
...
// Listen to sharedData post variable,
// and update local variable when it changes
this._sharedData.post.subscribe((post: PostPlaceholder) => {
this.post = post;
});
}
...
generatePost() {
// Generate Random Number
const randomPostId = Math.ceil(Math.random() * 9) + 1;
// Tell sharedData to get a new post by the random number
this._sharedData.fetchPost( randomPostId );
}
}