Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Learning Ionic, Second Edition
Learning Ionic, Second Edition

Learning Ionic, Second Edition: Hybrid mobile apps with HTML5, CSS3, and Angular , Second Edition

eBook
€20.98 €29.99
Paperback
€36.99
Subscription
Free Trial
Renews at €18.99p/m

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Table of content icon View table of contents Preview book icon Preview Book

Learning Ionic, Second Edition

Angular - A Primer

When Sir Timothy Berners-Lee invented the Internet, he never anticipated that the Internet would be used to publish selfies, share cat videos, or bomb web page with ads. His main intention (guessing) was to create a web of documents so a user on the Internet can access these hypertexts from anywhere and make use of it.

An interesting article published by Craig Buckler at Sitepoint titled, The Web Runs Out of Disk Space (http://www.sitepoint.com/web-runs-disk-space/), shows how the content on the Internet is spread out:

  • 28.65% pictures of cats
  • 16.80% vain selfies
  • 14.82% pointless social media chatter
  • 12.73% inane vlogger videos
  • 9.76% advertising/clickbait pages
  • 8.70% scams and cons
  • 4.79% articles soliciting spurious statistics
  • 3.79% new JavaScript tools/libraries
  • 0.76% documents for the betterment of human knowledge

You can see, since the invention of the Internet to the present day, how we have evolved. Better evolution needs better frameworks to build and manage such apps that need to be scalable, maintainable, and testable. This is where Angular stepped in back in 2010 to fill the gap and it has been evolving quite well since then.

We are going to start our journey by understanding the new changes to Angular, the importance of TypeScript, and see how Ionic 2 has adapted itself with Angular to help build performance-efficient and modern Mobile Hybrid apps.

In this chapter, we will take a quick peek at new topics added as part of Angular with the help of an example. The main changes that have taken place in Angular (2) are primarily on the lines of performance and componentization, apart from the language update. We will be going through the following topics in this chapter:

  • What is new in Angular?
  • TypeScript and Angular
  • Building a Giphy app

What is new in Angular?

Angular 2 is one of the most anticipated and dramatic version upgrades I have seen for any software. Angular 1 was a boon to web/mobile web/hybrid app developers, where managing a lot of things was made easy. Not only did Angular 1 help restructure client-side app development, but it also provided a platform to build applications; not websites, but applications. Though the first release suffered performance issues when dealing with large datasets, the Angular team bounced back quite well with the later releases of Angular 1, that is, Angular 1.4.x and above, and fixed these performance issues by releasing a more stable version in the form of Angular (2).

Some of the new changes that have accompanied with Angular (2) are:

  • Speed and performance improvements.
  • Component based (not the typical MV*).
  • Angular CLI.
  • Simple and expressive syntax.
  • Progressive Web Apps (PWA).
  • Cross-platform app development, which includes desktops, mobile, and web.
  • Cordova-based Hybrid app development.
  • Angular Universal provider for the server side for fast initial views.
  • Upgrades to better animation, internationalization, and accessibility.
  • Angular can be written on ES5, ES6, TypeScript, and Dart are based on the user's comfort with the JavaScript flavor.

With these new updates, developing apps has never been easier, be it on the desktop, mobile, or Mobile Hybrid environments.

Note: The latest version of Angular is going to be called just Angular, not Angular 2, or AngularJS 4, or NG4. So throughout this book, I will refer to Angular version 2 as Angular.

The current latest version of Angular is 4. Do checkout Chapter 11, Ionic 3, to know a bit more about Angular 4 and how it improves Ionic.

You can find more information about Angular here: https://angular.io.

Note: If you are new to Angular, you can refer to these books:

https://www.packtpub.com/web-development/learning-angular-2

https://www.packtpub.com/web-development/mastering-angular-2-components

https://www.packtpub.com/web-development/mastering-angular-2

https://www.packtpub.com/web-development/angular-2-example

Or these videos:

https://www.packtpub.com/web-development/angular-2-projects-video

https://www.packtpub.com/web-development/web-development-angular-2-and-bootstrap-video

https://www.packtpub.com/web-development/angular-2-web-development-TypeScript-video

TypeScript primer

Angular uses TypeScript extensively for app development. Hence as part of the Angular primer, we will refresh the necessary TypeScript concepts as well.

If you are new to TypeScript, TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. TypeScript provides static typing, classes, and interfaces and supports almost all features of ES6 and ES7 before they land in the browser.

A TypeScript file is saved with a .ts extension.

The main advantage of adding typings to an untyped language (JavaScript) is to make IDEs understand what we are trying to do and better assist us while coding; in other words, Intellisense.

Having said that, here is what we can do with TypeScript.

Variable typing

In vanilla JavaScript, we would do something like this:

x = 20; 
// after a few meaningful minutes
x = 'nah! It's not a number any more';

But in TypeScript, we cannot do as shown in the preceding code snippet, the TypeScript compiler would complain as we are modifying the variable type at runtime.

Defining types

When we declare variables, we can optionally declare the types of variables. For instance:

name: string = 'Arvind'; 
age: number = 99;
isAlive: boolean = true;
hobbies: string[];
anyType: any;
noType = 50;
noType = 'Random String';

This increases the predictability of what we are trying to do.

Classes

I am a guy who believes that JavaScript is an object-based programming language and not an object-oriented programming language, and I know quite a lot of people who disagree with me.

In vanilla JavaScript, we have functions, which act like a class and exhibit prototype-based inheritance. In TypeScript/ES6, we have the class construct:

class Person { 
name: string;

constructor(personName: string) {
this.name = personName;
}

getName {
return "The Name: " + this.greeting;
}
}
// somewhere else
arvind:Person = new Person('Arvind');

In the preceding example, we have defined a class named Person and we are defining the class constructor, which accepts the name on initialization of the class.

To initialize the class, we will invoke the class with a new keyword and pass in the name to the constructor. The variable that stores the instance of the class -- the object, arvind in the preceding example, can also be typed to the class. This helps in better understanding the possibilities of the arvind object.

Note: The classes in ES6 still follow Prototypal-based Inheritance and not the classical Inheritance model.

Interface

As we start building complex apps, there will be a common need for a certain type of structure to be repeated throughout the app, which follows certain rules. This is where an interface comes into the picture. Interfaces provide structural subtyping or duck typing to check the type and shape of entities.

For instance, if we are working with an app that deals with cars, every car will have a certain common structure that needs to be adhered to when used within the app. Hence we create an interface named ICar. Any class working with cars will implement this interface as follows:

Interface ICar { 
engine : String;
color: String;
price : Number;
}

class CarInfo implements ICar{
engine : String;
color: String;
price : Number;

constructor(){ /* ... */}
}

Modules and imports

In vanilla JavaScript, you must have observed code blocks like this:

(function(){ 
var x = 20;
var y = x * 30;
})(); //IIFE
// x & y are both undefined here.

Modules are achieved in ES6/TS using the imports and exports syntax:

logic.ts
export function process(){
x = 20;
y = x * 30;
}

exec.ts
import { process } from './logic';
process();

These are the bare essentials that we would need to get started with TypeScript. We will look at more such concepts where needed.

With this we wrap up the key concepts needed to get started with TypeScript. Let us get started with Angular.

For more information on TypeScript, check out: https://www.TypeScriptlang.org/docs/tutorial.html. Also check out the TypeScript introduction video: https://channel9.msdn.com/posts/Anders-Hejlsberg-Introducing-TypeScript.

Angular

Angular (2) has added a bunch of new features and updated existing features and removed a few over Angular 1.x. In this section, we will go through some of the essential features of Angular.

Components

Angular components are inspired by the Web Components specification. At a very high level, Web Components have four pieces:

  • Custom elements: A user can create their own HTML element.
  • HTML imports: Import one HTML document into another.
  • Templates: HTML definitions of the custom elements.
  • Shadow DOM: A specification to write encapsulated logic of custom elements.

The preceding four specifications explain how a frontend developer can develop their own standalone, isolated, and reusable components, similar to a HTML select box (<select></select>), or a text area (<textarea></textarea>), or an input (<input />).
You can read more about the Web Component specification here: https://www.w3.org/standards/techs/components#w3c_all.

If you would like to dig deeper into the Web Component, check out: http://webcomponents.org/.

As mentioned, Angular is (loosely) built on Web Components, where the preceding four specifications are implemented in an Angular way.

In simple terms, our entire app is a tree of components. For example, if we look at the world's most viewed page, https://www.google.com, it would look something like this:

And if we had to build this page in Angular, we would first split the page into components.

A visual representation of all the components that go into the preceding page would look like this:

Note: Each black box is a (custom) component.

As we can see from the preceding figure, the entire page is a tree of custom components.

A (custom) component would typically consist of three pieces:

  • component.ts: This represents the component logic
  • component.html: This represents the component view (template)
  • component.css: This represents the component specific styles

To build a custom component, we need to use a Component decorator on top of a class. In simple terms, a decorator lets us configure a class with specific metadata on them. This metadata will then be used by Angular to understand the behavior of that class. Decorators start with an @, followed by the name of the decorator.

The component decorator tells Angular that the class being processed needs to exhibit the behavior of an Angular component. A simple decorator would look as follows:

@Component({ 
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
// This is where we write the component logic!
title = 'Hello World!';
}

Some of the properties that go into a component decorator are:

  • selector: CSS selector that identifies this component in a template
  • templateUrl: URL to an external file containing a template for the view
  • styleUrls: List of URLs to style sheets to be applied to this component's view
  • providers : List of providers available to this component and its children
To know more about the Component decorator, refer to the following link: https://angular.io/docs/ts/latest/api/core/index/Component-decorator.html

Zones

Zones are one of the new concepts that have been introduced in Angular. The concept of Zones was migrated from Dart to JavaScript.

The main reason why a lot of developers were attracted towards Angular initially was by its Auto-magic Data Binding among other things. This was achieved using scopes in Angular 1.x. In Angular 2, we are using Zone.js (https://github.com/angular/zone.js) to achieve the same.

Whenever there is a change in the data, Angular updates the appropriate stakeholders (variables, interfaces, providers, and so on) with new data. Angular can track all synchronous activities quite easily. But for change detection in asynchronous code, such as event handling, AJAX calls, or Timers, Angular 2 uses Zone.js.

To know more about zones, how they work, and change detection in Angular, check out Zones in Angular: http://blog.thoughtram.io/angular/2016/02/01/zones-in-angular-2.html and Angular change detection explained: http://blog.thoughtram.io/angular/2016/02/22/angular-2-change-detection-explained.html.

Templates

Templates are used to bind the component logic to the HTML. Templates are also used as an interface between the user interaction of the user and app logic.

Templates have changed quite a bit when compared to version 1 of Angular. But there are a few things that still remain the same. For instance, the way we take a value from a component and display it in the user interface remains the same with the double curly brace notation (interpolation syntax).

The following is a sample app.component.ts:

@Component({ 
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
// This is where we write the component logic!
title = 'Hello World!';
}

The app.component.html would look something like this:

<h1>
{{title}} <!-- This value gets bound from app.component.ts -->
</h1>

Templates can also be made inline by passing in the template metadata to the decorator instead of templateUrl. This would look something like this:

 @Component({ 
selector: 'app-root',
template: '<h1>{{title}}</h1>',
styleUrls: ['./app.component.css']
})
export class AppComponent {
// This is where we write the component logic!
title = 'Hello World!';
}
The template metadata takes higher priority over templateUrl. For example, if we have defined both a template and templateUrl metadata, template is picked up and rendered.
We can also write multiline templates using backtick(`) instead of quotes, in both ES6 as well as TypeScript. For more information, refer to Template Literals: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Template_literals

In Angular 1.x, we have core/custom directives. But in Angular (2), we have various notations, using which we achieve the same behavior of a directive from Angular 1.

For instance, if we want to add a custom class to an element based on the truthiness of an expression, it would look this:

<div [class.highlight]="shouldHighlight">Hair!</div>

The preceding is a replacement for the famous ng-class Angular 1.x directive.

To handle events, we use the ( ) notation, as in:

<button (click)=pullHair($event)">Pull Hair</button>

And this pullhair() is defined inside the component class.

To keep the data bindings up to date, we use the [( )] notation, as in:

<input type="text" [(ngModel)]="name">

This keeps the name property in the component class in sync with the textbox.

An example of *ngFor, which is a replacement for ng-repeat, is shown here:

<ul> 
<li *ngFor="let todo in todos">{{todo.title}}</li>

</ul>

Note that let in front of todo indicates that it is a local variable in that zone.

These are some of the basic concepts that we need to get started with our hands-on example. I will talk about other Angular (2) concepts as and when they appear in our app.

Giphy app

Using the concepts we have learned so far, we are going to build a simple app using Angular and an Open JSON API provider named Giphy.

Giphy (http://giphy.com) is a simple Gif search engine. The guys at Giphy exposed an open REST API that we can consume and do a bunch of things with the data.

The app we are going to build is going to talk to the Giphy JSON API and return the results. Using Angular, we are going to build interfaces for three features in the app:

  • Show a random Gif
  • Show trending Gifs
  • Search a Gif

We will be using Angular CLI (https://cli.angular.io/) and Twitter Bootstrap (http://getbootstrap.com/) with the Cosmos theme (https://bootswatch.com/cosmo/).

Before we start building the app, let's first understand the app structure.

Architecture

The first thing we are going to look at is the architecture of the app. On the client side, we will have a router, from which all things start flowing. The router will have four routes:

  • Home route
  • Browse route
  • Search route
  • Page Not Found route

We will have one service, with three methods that will interact with the Giphy REST API.

Apart from the previously mentioned items, we will have the following components:

  • Nav Component: App Navbar
  • Home Component: Home Page which shows a random gif
  • Trending Component: Show trending gifs
  • Search Component: Search a gif
  • Giphy Component: Template for a gif
  • Page not found Component: To show a page that tells the user that nothing is found

The component tree for this would look as follows:

API

The Giphy API is quite easy to understand and use. You can find the official API documents here: https://github.com/Giphy/GiphyAPI.

The APIs that we are going to consume are:

You can navigate to the preceding links to see the sample data.

At the time of writing, Giphy exposed dc6zaTOxFJmzC as the API key to use.

Angular CLI

To develop our Giphy app, we are going to use Angular CLI. If you are new to the CLI and its features, I recommend checking out this video: Simple Angular 2 App With Angular CLI: https://www.youtube.com/watch?v=QMQbAoTLJX8.
This example is written with Angular CLI version 1.0.0-beta.18.

Installing software

For us to successfully develop the Angular-Giphy App, we need to have Node.js installed (https://nodejs.org/en). We will be using NPM (https://www.npmjs.com) to download the required modules via the Angular CLI.

Once Node.js is installed, open a new command prompt/terminal and run the following:

npm install -g @angular/cli

This will go ahead and install the Angular CLI generator. That is all we would need to start developing our app.

Note: I have used angular-cli version 1.0.0 to build this app.

Text editors

Regarding text editors, you can use any editor to work with Angular as well as Ionic. You can also try Sublime text (http://www.sublimetext.com/3) or Atom editor (https://atom.io/) or Visual Studio Code (https://code.visualstudio.com/) for working with the code.

If you are using Sublime text, you can take a look at: https://github.com/Microsoft/TypeScript-Sublime-Plugin to add TypeScript intelligence to your editor. And for Atom, refer to the following link: https://atom.io/packages/atom-TypeScript.

Scaffolding an Angular 2 app

The first thing we are going to do is scaffold an Angular app using the Angular CLI. Create a new folder named chapter1 and open a command prompt/terminal in that folder and run the following:

ng new giphy-app

Now Angular CLI generator will go ahead and create all the files and folders necessary to work with our Angular app.

As mentioned earlier, you can check out Simple Angular 2 app with Angular CLI: https://www.youtube.com/watch?v=QMQbAoTLJX8, as well to go through Angular CLI docs: https://cli.angular.io/reference.pdf to know more about it.

The scaffolded project structure would look as follows:

. 
├── .angular-cli.json
├── .editorconfig
├── README.md
├── e2e
│ ├── app.e2e-spec.ts
│ ├── app.po.ts
│ ├── tsconfig.e2e.json
├── karma.conf.js
├── node_modules
├── package.json
├── protractor.conf.js
├── src
│ ├── app
│ │ ├── app.component.css
│ │ ├── app.component.html
│ │ ├── app.component.spec.ts
│ │ ├── app.component.ts
│ │ ├── app.module.ts
│ ├── assets
│ │ ├── .gitkeep
│ ├── environments
│ │ ├── environment.prod.ts
│ │ ├── environment.ts
│ ├── favicon.ico
│ ├── index.html
│ ├── main.ts
│ ├── polyfills.ts
│ ├── styles.css
│ ├── test.ts
│ ├── tsconfig.app.json
│ ├── tsconfig.spec.json
│ ├── typings.d.ts
├── tsconfig.json
├── tslint.json

We will be spending most of our time inside the src folder. Once the project is completely scaffolded, cd into the giphy-app folder and run the following:

ng serve

This will start the built-in server. Once the build is completed, we can navigate to http://localhost:4200 to view the page. The page should look something like this:

Building the Giphy app

Now that we have all the pieces to get started, we will start off by adding Twitter Bootstrap CSS to the app.

For this example, we will be using a Bootstrap theme from https://bootswatch.com/ named Cosmos. We can find the Cosmos CSS theme on the theme page: https://bootswatch.com/cosmo/, by clicking on the Cosmos dropdown and selecting the bootstrap.min.css option. Or alternatively, we can find it here: https://bootswatch.com/cosmo/bootstrap.min.css.

If you want, you can use any other theme or the vanilla Bootstrap CSS as well.

To add the theme file, navigate to giphy-app/src/styles.css and add the following line inside it:

@import "https://bootswatch.com/cosmo/bootstrap.min.css";

That is it, now our app is powered with Twitter Bootstrap CSS.

Next, we will start working on our app's main page. For that we will be leveraging an example template from Twitter Bootstrap named the Starter Template. The template can be found here: http://getbootstrap.com/examples/starter-template/.

The Starter template consists of a navigation bar and a body section where the content gets displayed.

For the Navbar section, we will be generating a new component named nav-bar and updating the relevant code in it.

To generate a new custom component using Angular CLI, navigate to the giphy-app folder and run the following:

ng generate component nav-bar

Note: You can either kill the current running command or spawn a new command prompt/terminal to run the preceding command.

And you should see something like this:

create src/app/nav-bar/nav-bar.component.css
create src/app/nav-bar/nav-bar.component.html
create src/app/nav-bar/nav-bar.component.spec.ts
create src/app/nav-bar/nav-bar.component.ts
update src/app/app.module.ts

Now open giphy-app/src/app/nav-bar/nav-bar.component.html and update it as follows:

<nav class="navbar navbar-inverse navbar-fixed-top"> 
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" [routerLink]="['/']">Giphy App</a>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li [routerLinkActive]="['active']"><a [routerLink]="
['/trending']">Trending</a></li>
<li [routerLinkActive]="['active']"><a [routerLink]="
['/search']">Search</a></li>
</ul>
</div>
</div>
</nav>

All we are doing here is creating the header bar with two menu items and the app name, which acts as a link to the home page.

Next, we will update the giphy-app/src/app/app.component.html to load the nav-bar component. Replace the contents of that file with the following:

<nav-bar></nav-bar>

Next, we will start adding routes to the app. As discussed earlier, we are going to have three routes.

To add routing support to the current app, we need to do three things:

  1. Create the routes needed.
  2. Configure @NgModule.
  3. Tell Angular where to load the content of these routes.

At the time of writing, Angular CLI has disabled route generation. Hence we are going to create the same manually. Otherwise we could simply run ng generate route home to generate the home route.

So first, let's define all the routes. Create a new file named app.routes.ts inside the app folder. Update the file as follows:

import { HomeComponent } from './home/home.component'; 
import { TrendingComponent } from './trending/trending.component';
import { SearchComponent } from './search/search.component';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';

export const ROUTES = [
{ path: '', component: HomeComponent },
{ path: 'trending', component: TrendingComponent },
{ path: 'search', component: SearchComponent },
{ path: '**', component: PageNotFoundComponent }
];

All we have done here is exported an array of routes. Do notice the path '**'. This is how we define the other section of the routes.

We will create the required components now. Run the following:

ng generate component home
ng generate component trending
ng generate component search
ng generate component pageNotFound

Next, we will configure the @NgModule. Open giphy-app/src/app/app.module.ts and add the following imports at the top:

import { RouterModule }   from '@angular/router'; 
import { ROUTES } from './app.routes';

Next, update the imports property of the @NgModule decorator as follows:

//.. snipp 
imports: [
BrowserModule,
FormsModule,
HttpModule,
RouterModule.forRoot(ROUTES)
],
//.. snipp

The completed page would look as follows:

import { BrowserModule } from '@angular/platform-browser'; 
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { RouterModule } from '@angular/router';

import { AppComponent } from './app.component';
import { NavBarComponent } from './nav-bar/nav-bar.component';
import { HomeComponent } from './home/home.component';
import { TrendingComponent } from './trending/trending.component';
import { SearchComponent } from './search/search.component';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';

import { ROUTES } from './app.routes';

@NgModule({
declarations: [
AppComponent,
NavBarComponent,
HomeComponent,
TrendingComponent,
SearchComponent,
PageNotFoundComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
RouterModule.forRoot(ROUTES)
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

Now we will update the app component to show the Navbar as well as the current route content.

Update the giphy-app/src/app/app.component.html as follows:

<app-nav-bar></app-nav-bar> 
<router-outlet></router-outlet>

Using the router-outlet, we tell the router to load the current route content at that location.

If you want to know more about routing in Angular, you can check out: Routing in Eleven Dimensions with Component Router by Brian Ford: https://www.youtube.com/watch?v=z1NB-HG0ZH4.

Next, we will update the home component HTML and test the app so far.

Open giphy-app/src/app/home/home.component.html and update it as follows:

<div class="container"> 
<div class="starter-template">
<h1>Giphy App</h1>
<p class="lead">This app uses the JSON API provided by Giphy to Browse and Search Gifs.
<br> To know more checkout : <a href="https://github.com/Giphy/GiphyAPI#trending-gifs-endpoint">Giphy API</a> </p>
</div>
</div>

Once this is done, save the file and run the following:

ng  serve

And we should see the following page:

As we can see, the page looks broken. Let's fix this by adding a couple of styles. Open giphy-app/src/styles.css and add the following:

body {
padding-top: 50px;
padding-bottom: 20px;
}

.starter-template {
padding: 40px 15px;
text-align: center;
}

Now our page will look as expected:

Next, we will start by writing the service to talk to the Giphy API. We will be writing three methods, one to get a random gif, one to get the latest trends, and one to search the Gif API with a keyword.

To get started, we will generate a service. Run the following:

ng generate service giphy

WARNING Service is generated but not provided, it must be provided to be used

As shown in the warning, the service that has been generated has not been marked as a provider. So we need to do that manually.

Open giphy-app/src/app/app.module.ts and import the GiphyService:

import { GiphyService } from './giphy.service';

Next, add the GiphyService as a provider in the @NgModule decorator, providers property:

//.. snipp 
providers: [
GiphyService
],
//..snipp

The complete giphy-app/src/app/app.module.ts would look as follows:

import { BrowserModule } from '@angular/platform-browser'; 
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { RouterModule } from '@angular/router';

import { AppComponent } from './app.component';
import { NavBarComponent } from './nav-bar/nav-bar.component';
import { HomeComponent } from './home/home.component';
import { TrendingComponent } from './trending/trending.component';
import { SearchComponent } from './search/search.component';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';

import { ROUTES } from './app.routes';

import { GiphyService } from './giphy.service';

@NgModule({
declarations: [
AppComponent,
NavBarComponent,
HomeComponent,
TrendingComponent,
SearchComponent,
PageNotFoundComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
RouterModule.forRoot(ROUTES)
],
providers: [
GiphyService
],
bootstrap: [AppComponent]
})
export class AppModule { }

Now we will update the giphy-app/src/app/giphy.service.ts with the three methods. Open giphy-app/src/app/giphy.service.ts and update it as follows:

import { Injectable } from '@angular/core'; 
import { Http, Response, Jsonp } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import 'rxjs/Rx';

@Injectable()
export class GiphyService {
private giphyAPIBase = 'http://api.giphy.com/v1/gifs';
private APIKEY = 'dc6zaTOxFJmzC';

constructor(private http: Http) { }

getRandomGif(): Observable<Response> {
return this.http.get(this.giphyAPIBase +
'/random?api_key=' + this.APIKEY)
.map((res) => res.json());
}

getTrendingGifs(offset, limit): Observable<Response> {
return this.http.get(this.giphyAPIBase +
'/trending?api_key=' + this.APIKEY + '&offset=' + offset +
'&limit=' + limit)
.map((res) => res.json());
}

searchGifs(offset, limit, text): Observable<Response> {
return this.http.get(this.giphyAPIBase + '/search?api_key=' +
this.APIKEY + '&offset=' + offset +
'&limit=' + limit + '&q=' + text)
.map((res) => res.json());
}
}

All we are doing here is making an HTTP GET request to the corresponding Giphy API URLs and returning an Observable.

In RxJS (http://reactivex.io/rxjs/), an Observable is an entity, which can change over a period of time. This is the most basic building block of RxJS. An Observer subscribes to an Observable and reacts to its changes. This pattern is called a Reactive pattern.

Quoting from the documentation:

This pattern facilitates concurrent operations because it does not need to block while waiting for the Observable to emit objects, but instead it creates a sentry in the form of an observer that stands ready to react appropriately at whatever future time the Observable does so.

If you are new to Observables, you can start here: http://reactivex.io/documentation/observable.html followed by: Taking advantage of Observables in Angular: http://blog.thoughtram.io/angular/2016/01/06/taking-advantage-of-observables-in-angular2.html and Angular 2 HTTP requests with Observables: https://scotch.io/tutorials/angular-2-http-requests-with-observables.

Now that the service is completed, we will update the HomeComponent to get a random gif and display it on the home page.

Open giphy-app/src/app/home/home.component.ts and update it as follows:

import { Component, OnInit } from '@angular/core'; 
import { GiphyService } from '../giphy.service';

@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
public gif: string;
public result: any;
public isLoading: boolean = true;

constructor(private giphyService: GiphyService) {
this.getRandomGif();
}

ngOnInit() {
}

getRandomGif() {
this.giphyService.getRandomGif().subscribe(
(data) => {
this.result = data;
this.gif = this.result.data.image_url;
this.isLoading = false;
},
(err) => console.log('Oops!', err),
() => console.log('Response', this.result)
)
}
}

In the preceding code, first off, we have imported GiphyService and added it to the constructor. Next, we have written getRandomGif() and invoked getRandomGif() from the constructor. In getRandomGif(), we have invoked getRandomGif() on giphyService to get a random gif. We are then assigning the gif to a class variable named gif.

Just to see if everything is working fine, we will run the app by executing ng serve and opening developer tools. If everything goes well, we should see the response from the Giphy API:

Now that we have the response, we want to build a component that will display the gif. We want to build a separate component for this because we will be using the same component on other pages as well to display a gif where needed.

Let's go ahead and scaffold the component. Run the following:

ng generate component gif-viewr

Next, open giphy-app/src/app/gif-viewr/gif-viewr.component.html and update it as follows:

<div class="item"> 
<div class="well">
<img src="{{imgUrl}}">
</div>
</div>

Once this is done, we need to tell the component to expect the data from the parent component, as the home component will pass the imgUrl to the gif-viewer component.

Open giphy-app/src/app/gif-viewr/gif-viewr.component.ts. First, update the import statement by adding a reference to the Input decorator:

import { Component, OnInit, Input} from '@angular/core';

Next, add an Input decorator to the imgUrl variable:

@Input() imgUrl: string;

The updated giphy-app/src/app/gif-viewr/gif-viewr.component.ts would look as follows:

import { Component, OnInit, Input} from '@angular/core'; 

@Component({
selector: 'app-gif-viewr',
templateUrl: './gif-viewr.component.html',
styleUrls: ['./gif-viewr.component.css']
})
export class GifViewrComponent implements OnInit {
@Input() imgUrl: string;

constructor() { }

ngOnInit() {
}
}
Note: To define an input for a component, we use the @Input decorator. To know more about the @Input decorator, refer to the Attribute Directives section in Angular docs: https://angular.io/docs/ts/latest/guide/attribute-directives.html.

Save the file and open giphy-app/src/app/home/home.component.html. We will add the app-gif-viewr component inside this page:

<app-gif-viewr class="home" [imgUrl]="gif"></app-gif-viewr>

The complete file would look as follows:

<div class="container"> 
<div class="starter-template">
<h1>Giphy App</h1>
<p class="lead">This app uses the JSON API provided by Giphy to
Browse and Search Gifs.
<br> To know more checkout :
<a href=
"https://github.com/Giphy/GiphyAPI#trending-gifs-endpoint">
Giphy API</a> </p>
</div>

<app-gif-viewr class="home" [imgUrl]="gif"></app-gif-viewr>
</div>

Next, we will update CSS to beautify the page. Open giphy-app/src/styles.css and add the following CSS to the existing styles:

.home .well{ 
width: 70%;
margin: 0 auto;
}

img{
width: 100%;
}

If we go back to the browser and refresh, we should see the following:

And every time we refresh a page, we will see a new gif come up.

Next, we are going to work on the Trending page. This page will show gifs that are trending using the Pintrest layout (or Masonry layout). The Trending REST API supports pagination. We will be making use of this to load 12 gifs at a time. And then provide a Load More button to fetch the next 12 gifs.

First, let's get the data from the Giphy API. Open giphy-app/src/app/trending/trending.component.ts. We will first import the GiphyService:

import { GiphyService } from '../giphy.service';

Now, we will add the same to the constructor and update the constructor to invoke getTrendingGifs():

constructor(private giphyService: GiphyService) { } 
In ngOnInit(), we will call the getTrendingGifs() API:
ngOnInit() {
this.getTrendingGifs(this.offset, this.perPage);
}
Next, we will add the required class variables:
private offset = 0;
private perPage = 12;
public results: any;
public gifs: Array<any> = [];
public isLoading: boolean = true;

offset and perPage will be used to manage pagination.

results will be used to store the response from the server.

gifs is the array consisting of an array of trending gifs that we are exposing to the template.

isLoading is a boolean variable to keep track if a request is in progress or not. Using isLoading, we will show/hide the Load More button.

Next, we will add getTrendingGifs():

getTrendingGifs(offset, limit) { 
this.giphyService.getTrendingGifs(offset, limit).subscribe(
(data) => {
this.results = data;
this.gifs = this.gifs.concat(this.results.data);
this.isLoading = false;
},
(err) => console.log('Oops!', err),
() => console.log('Response', this.results)
)
}
And finally getMore(), which will be invoked by the Load More button:
getMore() {
this.isLoading = true;
this.offset = this.offset + this.perPage;
this.getTrendingGifs(this.offset, this.perPage);
}

To display the gifs retrieved, we will update the trending component template. Open giphy-app/src/app/trending/trending.component.html and update it as follows:

<div class="container"> 
<h1 class="text-center">Trending Gifs</h1>
<div class="wrapper">
<app-gif-viewr [imgUrl]="gif.images.original.url" *ngFor="let gif of gifs"></app-gif-viewr>
</div>
<input type="button" value="Load More" class="btn btn-primary btn-block" *ngIf="!isLoading" (click)="getMore()">
</div>

All we are doing here is setting up app-gif-viewr to take the gif URL by applying an *ngFor directive on it. And at the bottom, a Load More button, so a user can load more gifs.

And finally to achieve the Pintrest/Masonry layout, we will add a couple of CSS rules. Open giphy-app/src/styles.css and add the following styles:

*, *:before, *:after { 
box-sizing: border-box !important;
}

.wrapper {
column-width: 18em;
column-gap: 1em;
}

.item {
display: inline-block;
padding: .25rem;
width: 100%;
}

.well {
position: relative;
display: block;
}

Save all the files and head back to the browser. If we click on the trending menu item in the Navbar, we should see the following:

And if we scroll down completely, we should see a Load More button:

Clicking on the Load More button will load the next set of gifs:

I wasted about 15 minutes clicking Load More and watching the gifs. I think this is why APIs should have a rate limit.

Finally, we will implement searching gif. Open giphy-app/src/app/search/search.component.ts and import GiphyService:

import { GiphyService } from '../giphy.service';

Add giphyService as a class variable in the constructor:

constructor(private giphyService: GiphyService) { }

Next, we will add variables to manage pagination as well as the response:

  private offset = 0; 
private perPage = 12;
public results: any;
public query: string;
public gifs: Array<any> = [];
public isLoading: boolean = true;

Now we will invoke searchGifs, which makes a REST call to get the searched gifs, by passing in the query string:

searchGifs(offset, limit, query) { 
this.giphyService.searchGifs(offset, limit, query).subscribe(
(data) => {
this.results = data;
this.gifs = this.gifs.concat(this.results.data);
this.isLoading = false;
},
(err) => console.log('Oops!', err),
() => console.log('Response', this.results)
)
}

The following is a method to manage the search form submit button:

  search(query) { 
this.query = query;
this.isLoading = true;
this.searchGifs(this.offset, this.perPage, this.query);
}

And finally, getMore() to load more pages of the same query:

getMore() { 
this.isLoading = true;
this.offset = this.offset + this.perPage;
this.searchGifs(this.offset, this.perPage, this.query);
}

The updated giphy-app/src/app/search/search.component.ts would look as follows:

import { Component, OnInit } from '@angular/core'; 
import { GiphyService } from '../giphy.service';

@Component({
selector: 'app-search',
templateUrl: './search.component.html',
styleUrls: ['./search.component.css']
})
export class SearchComponent implements OnInit {
private offset = 0;
private perPage = 12;
public results: any;
public query: string;
public gifs: Array<any> = [];
public isLoading: boolean = true;

constructor(private giphyService: GiphyService) { }

ngOnInit() {
}

searchGifs(offset, limit, query) {
this.giphyService.searchGifs(offset, limit, query).subscribe(
(data) => {
this.results = data;
this.gifs = this.gifs.concat(this.results.data);
this.isLoading = false;
},
(err) => console.log('Oops!', err),
() => console.log('Response', this.results)
)
}

search(query) {
this.query = query;
this.isLoading = true;
this.searchGifs(this.offset, this.perPage, this.query);
}

getMore() {
this.isLoading = true;
this.offset = this.offset + this.perPage;
this.searchGifs(this.offset, this.perPage, this.query);
}
}

Now we will update the giphy-app/src/app/search/search.component.html. Open giphy-app/src/app/search/search.component.html and update it as follows:

<div class="container"> 
<h1 class="text-center">Search Giphy</h1>
<div class="row">
<input class="form-control" type="text" placeholder="Search
something.. Like.. LOL or Space or Wow" #searchText
(keyup.enter)="search(searchText.value)">
</div>
<br>
<div class="wrapper">
<app-gif-viewr [imgUrl]="gif.images.original.url" *ngFor="let
gif of gifs"></app-gif-viewr>
</div>
<input type="button" value="Load More" class="btn btn-primary btn-block" *ngIf="!isLoading" (click)="getMore()">
</div>

This view is the same as the Trending component, except there is a search textbox, which will allow the user to search by entering a string.

If we save all the files, go back to the browser, and navigate to the Search page, we should see an empty page with a search textbox. At this point, the load more button will not be shown. If we enter text and hit the return key, we should see results, as shown in the following screenshot:

With this we have completed the implementation of a Giphy API with an Angular app.

To bring this example to a closure, we will update giphy-app/src/app/page-not-found/page-not-found.component.html as follows:

<div class="container"> 
<div class="starter-template">
<h1>404 Not Found</h1>
<p class="lead">Looks Like We Were Not Able To Find What You Are Looking For.
<br>Back to : <a [routerLink]="['/']">Home</a>? </p>
</div>
</div>

And when we navigate to http://localhost:4200/nopage, we should see the following page:

Summary

In this chapter, we have gone through a high level overview of TypeScript and why we use TypeScript. Next we got acquainted with Angular's new syntax and the component structure. Using this knowledge, we have built an app named Giphy, which interfaces with the Giphy REST API to get gifs.

You can read more about Angular here: https://angular.io.

Also, check out Chapter 11, Ionic 3, to know more about the changes to Angular 4.

In the next chapter -- Welcome to Ionic, we will get started with Mobile Hybrid development using Cordova and we will look at how Ionic fits into the bigger scheme of things.

Left arrow icon Right arrow icon
Download code icon Download Code

Key benefits

  • Step into the world of amazingly interactive and real-time app development using Ionic 2
  • Leverage the powerful Angular 2 along with Ionic to develop cutting edge apps
  • Detailed code examples and explanations will help you get up and running with Ionic quickly and easily

Description

Ionic makes it incredibly easy to build beautiful and interactive mobile apps using HTML5, SCSS, and Angular. Ionic also makes app development easier, faster, and more fun. This hands-on guide will help you understand the Ionic framework and how you can leverage it to create amazing real-time applications. We begin by covering the essential features of Angular 2, and then dive straight into how Ionic fits in today’s world of hybrid app development and give you a better understanding of the mobile hybrid architecture along the way. Further on, you will learn how to work with Ionic decorators, services, and components, which will allow you to build complex apps using the Ionic framework. We will take a look at theming Ionic apps using the built-in SCSS setup. After that, we will explore Ionic Native, and you will learn how to integrate device-specific features, such as notifications, with the Ionic app. To complete our learning, we will be building a Rider app, using Ionic and Uber API, to book a ride. Next, you will learn how to unit test, end-to-end test, monkey test, and execute device testing on AWS Device farm. Then, we will take a look at migrating the existing Ionic 1 apps to Ionic 2 and deploy them to the App Store. The final chapter on Ionic 3 wraps up this book by explaining the new features of Ionic 3 at the time of writing this book. By the end of this book, you will be able to develop, deploy, and manage hybrid mobile applications built with Cordova, Ionic, and Angular. All the examples in this book are valid for both Ionic 2 and Ionic 3.

Who is this book for?

This book is for JavaScript developers with basic skills. No previous knowledge of Ionic is required for this book.

What you will learn

  • Understanding the world of the mobile hybrid architecture
  • Scaffolding and working with Ionic templates
  • Transforming a single page app to a multi-page app using Navigation Controller
  • Integrating Ionic components, decorators, and services and rapidly developing complex applications
  • Theming Ionic apps as well as customizing components using SCSS
  • Working with Ionic Native to interface with device features, such as camera, notifications, and battery
  • Building a production grade app using Ionic and Uber API to let users book a ride
  • Migrating an Ionic 1 app to Ionic 2 or Ionic 3
  • Performing unit testing, end-to-end testing, and device testing on your apps
  • Deploying Ionic apps to store and manage their subsequent releases
Estimated delivery fee Deliver to Estonia

Premium delivery 7 - 10 business days

€25.95
(Includes tracking information)

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Apr 28, 2017
Length: 378 pages
Edition : 2nd
Language : English
ISBN-13 : 9781786466051
Vendor :
Drifty
Category :
Languages :
Tools :

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Estimated delivery fee Deliver to Estonia

Premium delivery 7 - 10 business days

€25.95
(Includes tracking information)

Product Details

Publication date : Apr 28, 2017
Length: 378 pages
Edition : 2nd
Language : English
ISBN-13 : 9781786466051
Vendor :
Drifty
Category :
Languages :
Tools :

Packt Subscriptions

See our plans and pricing
Modal Close icon
€18.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
€189.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts
€264.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total 133.97
Ionic: Hybrid Mobile App Development
€59.99
Ionic 2 Cookbook
€36.99
Learning Ionic, Second Edition
€36.99
Total 133.97 Stars icon

Table of Contents

11 Chapters
Angular - A Primer Chevron down icon Chevron up icon
Welcome to Ionic Chevron down icon Chevron up icon
Ionic Components and Navigation Chevron down icon Chevron up icon
Ionic Decorators and Services Chevron down icon Chevron up icon
Ionic and SCSS Chevron down icon Chevron up icon
Ionic Native Chevron down icon Chevron up icon
Building the Riderr App Chevron down icon Chevron up icon
Ionic 2 Migration Guide Chevron down icon Chevron up icon
Testing an Ionic 2 App Chevron down icon Chevron up icon
Releasing the Ionic App Chevron down icon Chevron up icon
Ionic 3 Chevron down icon Chevron up icon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact customercare@packt.com with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at customercare@packt.com using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on customercare@packt.com with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on customercare@packt.com within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on customercare@packt.com who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on customercare@packt.com within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela