You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<p>With this setup you now have a <code>User</code> class that you can share across pages in your app and even across applications. But a model object that’s four simple lines of code isn’t all that exciting. Where this approach really pays off is when you’re able to share your business logic, and the code that hits your backend systems. In Angular 2 those classes are known as services. Let’s look at them next.</p>
739
739
<h3id="services">Services</h3>
740
-
<p>A login screen isn’t all that useful if it doesn’t actually log users into anything. Therefore, our next task is to take the user’s email address and password, and send them to a backend endpoint to retrieve an authentication token we’ll use later in this guide. We’ll build this functionality as an Angular 2 service.</p>
740
+
<p>A login screen isn’t all that useful if it doesn’t actually log users into anything. Therefore, our next task is to allow users to create and log into accounts. We’ll build this functionality as an <ahref="https://angular.io/docs/ts/latest/tutorial/toh-pt4.html">Angular 2 service</a>, which is Angular 2’s mechanism for reusable classes that operate on data.</p>
741
741
<p>For the purposes of this tutorial we prebuilt a handful of backend endpoints using <ahref="http://www.telerik.com/platform/backend-services">Telerik Backend Services</a>, and we’ll be using those endpoints to make this app functional. Let’s see how they work.</p>
742
742
<blockquote>
743
743
<p><strong>NOTE</strong>: You don't have to use Telerik Backend Services to power your app’s backend; you can use any HTTP API in a NativeScript app. Telerik Backend Services is convenient for us to use for this tutorial because it lets us spin up HTTP endpoints quickly.</p>
@@ -746,6 +746,68 @@ <h4 class="exercise-start">
746
746
<b>Exercise</b>: Add an Angular 2 service
747
747
</h4>
748
748
749
+
<p>There’s are several new concepts to introduce with Angular services, so we’re going to start by stubbing out a new <code>register()</code> method, and then come back to the implementation later in this section. With that in mind, open <code>app/shared/user/user.service.ts</code> and paste in the following code:</p>
750
+
<pre><codeclass="lang-TypeScript">import {Injectable} from "angular2/core";
751
+
import {User} from "./user";
752
+
753
+
@Injectable()
754
+
export class UserService {
755
+
register(user: User) {
756
+
alert("About to register: " + user.email);
757
+
}
758
+
}
759
+
</code></pre>
760
+
<p>This creates a basic Angular service with a single method that takes an instance of the <code>User</code> object you created in the previous section. The one new thing is the <code>@Injectable</code> decorator. This decorator denotes this class as a candidate for <ahref="https://angular.io/docs/ts/latest/guide/dependency-injection.html">Angular’s dependency injection mechanism</a>. For now just think of adding the <code>@Injectable</code> as a required convention for all services that you write.</p>
761
+
<p>Next, add the following line to the top of <code>app/app.component.ts</code>, which imports the service you just defined:</p>
762
+
<pre><codeclass="lang-TypeScript">import {UserService} from "./shared/user/user.service";
763
+
</code></pre>
764
+
<p>After that, add a new <code>providers</code> property to the existing <code>@Component</code> decorator. The full <code>@Component</code> declaration should now look like this:</p>
<p>The <code>providers</code> array is a simple list of all the Angular 2 services that you need to use in your component. At the moment you only have one service, so your <code>providers</code> array only has one entry.</p>
773
+
<p>Next, replace <code>AppComponent</code>’s existing <code>constructor</code> with the code below:</p>
<p>We’ll discuss what this <code>constructor</code> syntax is doing momentarily, as it can be confusing if you’ve never worked with Angular 2 before, but first let’s make the final change to get this example running. Find the existing <code>submit()</code> function in <code>AppComponent</code>, and replace it with the following three functions:</p>
779
+
<pre><codeclass="lang-TypeScript">submit() {
780
+
if (this.isLoggingIn) {
781
+
this.login();
782
+
} else {
783
+
this.signUp();
784
+
}
785
+
}
786
+
login() {
787
+
// TODO: Define
788
+
}
789
+
signUp() {
790
+
this._userService.register(this.user);
791
+
}
792
+
</code></pre>
793
+
<divclass="exercise-end"></div>
794
+
795
+
<p>Now, in your app, tap the “Sign Up” button, type an email address, and tap the “Sign Up” button again. If all went well, you should see the alert below:</p>
796
+
<p><imgsrc="images/chapter3/android/5.png" alt="Alert on Android">
797
+
<imgsrc="images/chapter3/ios/5.png" alt="Alert on iOS"></p>
798
+
<p>How does this code work? Let’s return to this bit of code:</p>
<p>This is Angular 2’s dependency injection implementation in action. Because you registered <code>UserService</code> as a provider in this component’s <code>providers</code> array, when Angular sees this syntax it creates an instance of the <code>UserService</code> class, and passes that instance into the component’s constructor.</p>
804
+
<p>This begs a bigger question though: why bother with all of this? Why not run <code>this._userService = new UserService()</code> in the component’s constructor and forget the complexity of <code>@Injectable</code> and <code>providers</code>?</p>
805
+
<p>The short answer is a dependency-injection-based approach to coding keeps your classes less coupled, and therefore more maintainable and testable as your application evolves over time. For a longer answer, head over to the Angular for a <ahref="https://angular.io/docs/ts/latest/guide/dependency-injection.html">more thorough discussion of the benefits of dependency injection</a>.</p>
806
+
<p>Let’s return to our example and make the registration process actually work.</p>
807
+
<h4class="exercise-start">
808
+
<b>Exercise</b>: Use an Angular 2 service
809
+
</h4>
810
+
749
811
<p>Open <code>app/shared/user/user.service.ts</code> and paste in the following code:</p>
750
812
<pre><codeclass="lang-TypeScript">import {Injectable} from "angular2/core";
751
813
import {Http, Headers, Response} from "angular2/http";
@@ -781,33 +843,8 @@ <h4 class="exercise-start">
781
843
}
782
844
}
783
845
</code></pre>
784
-
<p>TODO: Explain that mess above, and probably break it into a lot of steps.</p>
785
-
<p>In <code>app.component.ts</code>, add the lines below to the top:</p>
786
-
<pre><codeclass="lang-TypeScript">import {HTTP_PROVIDERS} from "angular2/http";
787
-
import {UserService} from "./shared/user/user.service";
<p>The <code>UserService</code> class is using the same dependency injection technique to bring in a service that it needs, in this case the Http class, which is Angular 2’s way of letting you perform HTTP calls. And thanks to NativeScript, those same HTTP APIs work on iOS and Android without any extra work.</p>
864
+
<blockquote>
865
+
<p><strong>TIP</strong>: Refer to <ahref="https://angular.io/docs/ts/latest/api/http/Http-class.html">Angular 2’s docs on Http</a> for specifics on what HTTP APIs are available.</p>
866
+
</blockquote>
867
+
<p>The other new bit of code is the return value of this new <code>register()</code> method. <code>register()</code> returns <code>this._http.post()</code>, which is an RxJS <code>Observable</code>. You can refer to docs for a <ahref="https://angular.io/docs/ts/latest/guide/server-communication.html">full tutorial on how RxJS observables work</a>, but for now just know that the most common thing you’ll need to do with observables is subscribe to them, which is what the new code you added to <code>app.component.ts</code> does:</p>
alert("Your account was successfully created.");
872
+
this.toggleDisplay();
873
+
},
874
+
() => alert("Unfortunately we were unable to create your account.")
875
+
);
876
+
</code></pre>
877
+
<blockquote>
878
+
<p><strong>NOTE</strong>: The <code>() => {}</code> syntax defines an <ahref="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions">ES2015 arrow function</a>, which TypeScript supports out of the box. In this example, the arrow functions are the equivalent of writing <code>function() {}</code>.</p>
879
+
</blockquote>
880
+
<p>The two functions you provide are success and failure handlers. If The call to <code>register()</code> succeeds, your first alert will fire, and if the call to <code>register()</code> fails, your second alert will fire. Now that your service code is setup and ready to go, let’s create make the final few changes and create an account.</p>
alert("Your account was successfully created.");
864
-
this.toggleDisplay();
865
-
},
866
-
() => alert("Unfortunately we were unable to create your account.")
867
-
);
868
-
}
869
-
toggleDisplay() {
870
-
this.isLoggingIn = !this.isLoggingIn;
871
-
}
872
-
}
885
+
<p>Because the <code>UserService</code> makes use of the Http service, your final step is registering the Http provider in <code>AppComponent</code>. Start by opening <code>app/app.component.ts</code> and adding the following import to the top of the file:</p>
886
+
<pre><codeclass="lang-TypeScript">import {HTTP_PROVIDERS} from "angular2/http";
873
887
</code></pre>
888
+
<p>Next, in the same file, replace the current <code>providers</code> array with the following code:</p>
<p>At this point you should be ready to create an account to verify this whole setup worked.</p>
892
+
<p>After the provider changes have livesync’d, click the “Sign Up” button in your app, type in an email address and password (fake credentials are fine, just make up something you can remember), and then click the orange “Sign Up” button.</p>
874
893
<divclass="exercise-end"></div>
875
894
876
-
<p>TODO: Show that user account creation now works and transition to routing.</p>
895
+
<p>If all went well, you should see a confirmation dialog that looks like this:</p>
896
+
<p><imgsrc="images/chapter3/android/6.png" alt="Alert on Android">
897
+
<imgsrc="images/chapter3/ios/6.png" alt="Alert on iOS"></p>
898
+
<blockquote>
899
+
<p><strong>TIP</strong>: After creating your account, you may wish to hardcore your credentials in your <code>AppComponent</code>’s <code>constructor</code> to make development faster for the rest of this guide.</p>
<p>Your app now has a fully functional registration process, but users can’t do anything with the accounts they create. Our next step is to allow the users to login and navigate to a new list page. And to do that we need to introduce the concept of routing.</p>
0 commit comments