Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Mobile Development for Angular Devs

DZone's Guide to

Mobile Development for Angular Devs

The AngularWithIonic project is a way for Angular developers to use their Angular and Typescript skills to create an app that can be deployed on a phone.

· Mobile Zone ·
Free Resource

The project AngularWithIonic shows how to develop a mobile app with Angular. The Ionic Framework offers app development with Angular and Typescript. That way, the skills of Angular developers can be reused in mobile app development and Ionic packages the project in a mobile app that can be deployed on a phone.

The App

The app offers a login to support multiple users on a smartphone and authenticates the user. The user can see the exchange rates of 4 cryptocurrencies of 2 exchanges. Each of the rates offers a detail page with a chart and a button to the order book page. The order book page offers access to the order book of the exchanges and sending of an order. The order can be seen and canceled on the orders page. To send the orders, the IDs and tokens have to be provided on the settings page. The ids and tokens are stored encrypted.

The Quotes Page

The quotes page shows the exchange rates of 4 cryptocurrencies of 2 exchanges. To do that, a page and 2 providers have been generated. To do that, run: ionic generate.

@IonicPage()
@Component({
  selector: 'page-quotes',
  templateUrl: 'quotes.html',
})
export class QuotesPage {
  bitcoinBs = <QuoteBs> {};
  etherBs = <QuoteBs> {};
  ltcBs = <QuoteBs> {};
  rippleBs = <QuoteBs> {};

  bitcoinBf = <QuoteBf> {};
  etherBf = <QuoteBf> {};
  ltcBf = <QuoteBf> {};
  rippleBf = <QuoteBf> {};


  constructor(public navCtrl: NavController, 
          public navParams: NavParams, 
          private bitstampServ: BitstampProvider, 
          private bitfinexServ: BitfinexProvider,
          private metadata: MetadataProvider) {
  }

  ionViewDidLoad() {
    this.bitstampServ.getCurrentQuote(this.bitstampServ.BTCUSD).subscribe(quote => this.bitcoinBs = quote);
    this.bitstampServ.getCurrentQuote(this.bitstampServ.ETHUSD).subscribe(quote => this.etherBs = quote);
    this.bitstampServ.getCurrentQuote(this.bitstampServ.LTCUSD).subscribe(quote => this.ltcBs = quote);
    this.bitstampServ.getCurrentQuote(this.bitstampServ.XRPUSD).subscribe(quote => this.rippleBs = quote);
    this.bitfinexServ.getCurrentQuote(this.bitfinexServ.BTCUSD).subscribe(quote => this.bitcoinBf = quote);
    this.bitfinexServ.getCurrentQuote(this.bitfinexServ.ETHUSD).subscribe(quote => this.etherBf = quote);
    this.bitfinexServ.getCurrentQuote(this.bitfinexServ.LTCUSD).subscribe(quote => this.ltcBf = quote);
    this.bitfinexServ.getCurrentQuote(this.bitfinexServ.XRPUSD).subscribe(quote => this.rippleBf = quote);
    console.log('ionViewDidLoad QuotesPage');
  }

  showDetails(exchange: string, curr: string) : void {
      //console.log(exchange+" "+curr);
      this.navParams.data.exchange = exchange;
      this.navParams.data.currency = curr;
      this.navCtrl.push(QuotedetailPage, this.navParams);
  }

  openSettings() {
      this.navCtrl.push(SettingsPage, this.navParams);
  }

  openOrders() {
      this.navCtrl.push(OrdersPage, this.navParams);
  }

  logout() {   
      this.metadata.password = null;
      this.navCtrl.popToRoot();
  }
}

In Lines 1-3, the annotations declare the ionic page and the component. The page needs to be declared in the app.module.ts file as "QuotesPageModule." The QuotesPageModule is generated by Ionic.

In Lines 7-15 are the properties of the exchange rate quotes.

In Line 18, the constructor starts with the NavController service. The NavController is used to navigate between the different pages of the app.

In Line 19 are the NavParams. The NavParams have the data object that serves as a map to store values that are needed in the context of the following pages. NavParams are similar to routing params.

In Lines 20-21, the Providers for the supported exchanges are injected. They are services that are called providers.

In Line 22, the MetadataProvider is injected. It is used to store data that is used in only a few pages.

In Lines 25-35, the method ionViewDidLoad() loads the quotes with the providers of the constructor after the page is loaded. All quotes are loaded concurrently because the provider subscriptions are asynchronous.

In Lines 37-42, the method showDetails() sets the values exchange and currency for the QuoteDetailPage and then calls push with the NavParams to show the page.

In Lines 44-50, are the methods that show the settings page and the order page the same way the QuoteDetailPage was opened.

In Lines 52-55, is the logout method sets the password in the MetadataProvider to null and then calls popToRoot() to remove all pages and show the login page.

The template of the quotes page looks like this:

<ion-header>

  <ion-navbar>
    <ion-title>Quotes</ion-title>
  </ion-navbar>

</ion-header>

<ion-content padding>
<ion-grid>
<ion-row>
  <ion-col col-12 class="exchange">Bitstamp</ion-col>
  </ion-row>
  <ion-row (click)="showDetails('bitstamp','btcusd')">
        <ion-col col-4>BitCoin</ion-col>
        <ion-col col-4>{{bitcoinBs?.last}}</ion-col>
        <ion-col col-4>{{bitcoinBs?.volume | number}}</ion-col>
  </ion-row>
  <ion-row (click)="showDetails('bitstamp','ethusd')">
        <ion-col col-4>Ether</ion-col>
        <ion-col col-4>{{etherBs?.last}}</ion-col>
        <ion-col col-4>{{etherBs?.volume | number}}</ion-col>
  </ion-row>
  <!-- two more quotes -->      
  <ion-row>
        <ion-col col-12 class="exchange">Bitfinex</ion-col>
  </ion-row>
  <ion-row   (click)="showDetails('bitfinex','btcusd')">
        <ion-col col-4>BitCoin</ion-col>
        <ion-col col-4>{{bitcoinBf?.last_price}}</ion-col>
        <ion-col col-4>{{bitcoinBf?.volume | number}}</ion-col>
  </ion-row>
  <ion-row   (click)="showDetails('bitfinex','ethusd')">
        <ion-col col-4>Ether</ion-col>
        <ion-col col-4>{{etherBf?.last_price}}</ion-col>
        <ion-col col-4>{{etherBf?.volume | number}}</ion-col>
  </ion-row>
      <!-- Two more quotes -->
  <ion-row>
  <ion-col col-12> 
  </ion-col>
  </ion-row>
  <ion-row>
  <ion-col col-12 class="centerButton">
          <button ion-button  (click)="openSettings()">Settings</button>
          <button ion-button  (click)="openOrders()">Orders</button>
          <button ion-button  (click)="logout()">Logout</button>
  </ion-col>
  </ion-row>
  </ion-grid>
</ion-content>

In Lines 3-5, the navigationBar at the top of the page is defined.

In Lines 14-18, a quote is defined. The row has a click event that calls the showDetails(...) method of the class. Line 17 has  bitcoinBs?.volume | number  to handle the case that bitconBs is not yet loaded and format the volume with the number pipe.

In Lines 44-48, the buttons for the settings page, the orders page, and the log out are displayed.

The Provider

The Provider for one of the exchanges looks like this:

@Injectable()
export class BitstampProvider {    

    private _reqOptionsArgs = { headers: new HttpHeaders().set( 'Content-Type', 'application/json' ) };
    private readonly _bitstamp = '/bitstamp';
    private readonly _bitstamp2 = '/bitstamp2';
    BTCUSD = 'btcusd';
    ETHUSD = 'ethusd';
    LTCUSD = 'ltcusd';
    XRPUSD = 'xrpusd';
    private _utils = new Utils(); 

    constructor(private http: HttpClient, private pl: PlatformLocation ) { 
    }

    getCurrentQuote(currencypair: string): Observable<QuoteBs> {
        return this.http.get(this._bitstamp+'/'+currencypair+'/current', this._reqOptionsArgs).catch(this._utils.handleError);
    }

    getTodayQuotes(currencypair: string): Observable<QuoteBs[]> {
        return this.http.get(this._bitstamp+'/'+currencypair+'/today', this._reqOptionsArgs).catch(this._utils.handleError);
    }

    getOrderbook(currencypair: string): Observable<OrderbookBs> {
        return this.http.get(this._bitstamp2+'/api/v2/order_book/'+currencypair+'/', this._reqOptionsArgs).catch(this._utils.handleError);
    }
    /*
    methods to make orders work
    */
}

In Line 1 is the injectable() annotation to make the provider injectable in the constructors. The provider has to be configured in the app.module.ts file.

In Line 4, the default Httpheader is set.

In Lines 5-6, the paths of the rest call are set. The calls are redirected by the proxy config.

In Lines 13-14 is the constructor that gets the HttpClient injected.

In Lines 16-18 is the method getCurrentQuote, which gets the quote of the current minute from the server. It returns an Observable with QuoteBs interface. If an exception happens, it is logged in the browser.

Development

The development of the app works like developing a web app with Angular-Cli.

The Ionic-Cli can be used to call ionic serve to start the app as a web application on port 8100. Then you can develop it locally as a usual web application. After some setup, the app can be built and deployed on a mobile device to test it. That enables a workflow that is quite similar to developing a web app.

Summary

If you compare the Angular code of AngularAndSpring with the Angular code of AngularWithIonic, it looks pretty similar. That makes switching between web frontends and mobile app development for Angular developers possible. Angular can be the frontend technology for Java EE, Spring, and mobile apps. With its similarities to the Java world, Angular is a path for Java developers to do frontend tasks in multiple environments.

Topics:
angular ,typescript ,ionic ,web dev ,mobile ,mobile app development

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}