|
@@ -322,6 +322,169 @@ The `LoginPage` tries to auto-focus onto the `email` field when it loads. To aut
|
322
|
322
|
<preference name="KeyboardDisplayRequiresUserAction" value="false" />
|
323
|
323
|
```
|
324
|
324
|
|
|
325
|
+Check your changes into Git.
|
|
326
|
+
|
|
327
|
+```
|
|
328
|
+git add .
|
|
329
|
+git commit -m "Add Stormpath"
|
|
330
|
+```
|
|
331
|
+
|
|
332
|
+## Build a Beer UI
|
|
333
|
+
|
|
334
|
+Run `ionic generate page beer` to create a component and a template to display the list of good beers.
|
|
335
|
+
|
|
336
|
+Run `ionic generate provider beer-service` to create a service to fetch the beer list from the Spring Boot API.
|
|
337
|
+
|
|
338
|
+Change `src/providers/beer-service.ts` to use have a `getGoodBeers()` method.
|
|
339
|
+
|
|
340
|
+```typescript
|
|
341
|
+import { Injectable } from '@angular/core';
|
|
342
|
+import { Http, Response } from '@angular/http';
|
|
343
|
+import 'rxjs/add/operator/map';
|
|
344
|
+import { Observable } from 'rxjs';
|
|
345
|
+import { StormpathConfiguration } from 'angular-stormpath';
|
|
346
|
+
|
|
347
|
+@Injectable()
|
|
348
|
+export class BeerService {
|
|
349
|
+ public API;
|
|
350
|
+ public BEER_API;
|
|
351
|
+
|
|
352
|
+ constructor(public http: Http, public config: StormpathConfiguration) {
|
|
353
|
+ this.API = config.endpointPrefix;
|
|
354
|
+ this.BEER_API = this.API + '/beers';
|
|
355
|
+ }
|
|
356
|
+
|
|
357
|
+ getGoodBeers(): Observable<any> {
|
|
358
|
+ return this.http.get(this.API + '/good-beers')
|
|
359
|
+ .map((response: Response) => response.json());
|
|
360
|
+ }
|
|
361
|
+}
|
|
362
|
+```
|
|
363
|
+
|
|
364
|
+Modify `beer.html` to
|
|
365
|
+
|
|
366
|
+```html
|
|
367
|
+<ion-header>
|
|
368
|
+ <ion-navbar>
|
|
369
|
+ <ion-title>Good Beers</ion-title>
|
|
370
|
+ </ion-navbar>
|
|
371
|
+
|
|
372
|
+</ion-header>
|
|
373
|
+
|
|
374
|
+<ion-content padding>
|
|
375
|
+ <ion-list>
|
|
376
|
+ <ion-item *ngFor="let beer of beers" >
|
|
377
|
+ <ion-item>
|
|
378
|
+ <h2>{{beer.name}}</h2>
|
|
379
|
+ </ion-item>
|
|
380
|
+ </ion-item>
|
|
381
|
+ </ion-list>
|
|
382
|
+</ion-content>
|
|
383
|
+```
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+Modify `beer.ts` to
|
|
387
|
+
|
|
388
|
+```typescript
|
|
389
|
+import { Component } from '@angular/core';
|
|
390
|
+import { BeerService } from '../../providers/beer-service';
|
|
391
|
+
|
|
392
|
+@Component({
|
|
393
|
+ selector: 'page-beer',
|
|
394
|
+ templateUrl: 'beer.html',
|
|
395
|
+ providers: [BeerService]
|
|
396
|
+})
|
|
397
|
+export class BeerPage {
|
|
398
|
+ private beers: Array<any>;
|
|
399
|
+
|
|
400
|
+ constructor(public beerService: BeerService) {
|
|
401
|
+ }
|
|
402
|
+
|
|
403
|
+ ionViewDidLoad() {
|
|
404
|
+ this.beerService.getGoodBeers().subscribe(beers => {
|
|
405
|
+ this.beers = beers;
|
|
406
|
+ })
|
|
407
|
+ }
|
|
408
|
+}
|
|
409
|
+```
|
|
410
|
+
|
|
411
|
+Add some fun with Giphy! Run `ionic generate provider giphy-service`. Replace the code in `src/providers/giphy-service.ts` with the following TypeScript:
|
|
412
|
+
|
|
413
|
+```typescript
|
|
414
|
+import { Injectable } from '@angular/core';
|
|
415
|
+import { Http, Response } from '@angular/http';
|
|
416
|
+import { Observable } from 'rxjs';
|
|
417
|
+
|
|
418
|
+@Injectable()
|
|
419
|
+// http://tutorials.pluralsight.com/front-end-javascript/getting-started-with-angular-2-by-building-a-giphy-search-application
|
|
420
|
+export class GiphyService {
|
|
421
|
+
|
|
422
|
+ giphyApi = 'https://api.giphy.com/v1/gifs/search?api_key=dc6zaTOxFJmzC&q=';
|
|
423
|
+
|
|
424
|
+ constructor(public http: Http) {
|
|
425
|
+ }
|
|
426
|
+
|
|
427
|
+ get(searchTerm): Observable<any> {
|
|
428
|
+ let apiLink = this.giphyApi + searchTerm;
|
|
429
|
+ return this.http.request(apiLink).map((res: Response) => {
|
|
430
|
+ let results = res.json().data;
|
|
431
|
+ if (results.length > 0) {
|
|
432
|
+ return results[0].images.original.url;
|
|
433
|
+ } else {
|
|
434
|
+ return 'https://media.giphy.com/media/YaOxRsmrv9IeA/giphy.gif'; // dancing cat for 404
|
|
435
|
+ }
|
|
436
|
+ });
|
|
437
|
+ }
|
|
438
|
+}
|
|
439
|
+```
|
|
440
|
+
|
|
441
|
+Update `beer.ts` to take advantage of `GiphyService`:
|
|
442
|
+
|
|
443
|
+```typescript
|
|
444
|
+import { Component } from '@angular/core';
|
|
445
|
+import { BeerService } from '../../providers/beer-service';
|
|
446
|
+import { GiphyService } from '../../providers/giphy-service';
|
|
447
|
+
|
|
448
|
+@Component({
|
|
449
|
+ selector: 'page-beer',
|
|
450
|
+ templateUrl: 'beer.html',
|
|
451
|
+ providers: [BeerService, GiphyService]
|
|
452
|
+})
|
|
453
|
+export class BeerPage {
|
|
454
|
+ private beers: Array<any>;
|
|
455
|
+
|
|
456
|
+ constructor(public beerService: BeerService, public giphyService: GiphyService) {
|
|
457
|
+ }
|
|
458
|
+
|
|
459
|
+ ionViewDidLoad() {
|
|
460
|
+ this.beerService.getGoodBeers().subscribe(beers => {
|
|
461
|
+ this.beers = beers;
|
|
462
|
+ for (let beer of this.beers) {
|
|
463
|
+ this.giphyService.get(beer.name).subscribe(url => {
|
|
464
|
+ beer.giphyUrl = url
|
|
465
|
+ });
|
|
466
|
+ }
|
|
467
|
+ })
|
|
468
|
+ }
|
|
469
|
+ ...
|
|
470
|
+}
|
|
471
|
+```
|
|
472
|
+
|
|
473
|
+Update `beer.html` to display the image retrieved:
|
|
474
|
+
|
|
475
|
+```html
|
|
476
|
+<ion-item>
|
|
477
|
+ <ion-avatar item-left>
|
|
478
|
+ <img src="{{beer.giphyUrl}}">
|
|
479
|
+ </ion-avatar>
|
|
480
|
+ <h2>{{beer.name}}</h2>
|
|
481
|
+</ion-item>
|
|
482
|
+```
|
|
483
|
+
|
|
484
|
+If everything works as expected, you should see a page similar to the one below in your browser.
|
|
485
|
+
|
|
486
|
+![Good Beers UI](./static/good-beers-ui.png)
|
|
487
|
+
|
325
|
488
|
## PWAs with Ionic
|
326
|
489
|
|
327
|
490
|
Ionic 2 ships with support for creating progressive web apps (PWAs). If you’d like to learn more about what PWAs are, see [Navigating the World of Progressive Web Apps with Ionic 2](http://blog.ionic.io/navigating-the-world-of-progressive-web-apps-with-ionic-2/).
|
|
@@ -439,6 +602,6 @@ I’d love to learn how to add [Touch ID](https://ionicframework.com/docs/v2/nat
|
439
|
602
|
|
440
|
603
|
To learn more about Ionic, Angular, or Stormpath, please see the following resources:
|
441
|
604
|
|
442
|
|
-[Get started with Ionic Framework](http://ionicframework.com/getting-started/)
|
443
|
|
-[Getting Started with Angular](https://www.youtube.com/watch?v=Jq3szz2KOOs) A YouTube webinar by yours truly. ;)
|
444
|
|
-[Stormpath Client API Guide](https://docs.stormpath.com/client-api/product-guide/latest/)
|
|
605
|
+* [Get started with Ionic Framework](http://ionicframework.com/getting-started/)
|
|
606
|
+* [Getting Started with Angular](https://www.youtube.com/watch?v=Jq3szz2KOOs) A YouTube webinar by yours truly. ;)
|
|
607
|
+* [Stormpath Client API Guide](https://docs.stormpath.com/client-api/product-guide/latest/)
|