Step 3. Creating the Service

What are Services?

Services are simply functions that are responsible for performing specific tasks. Some think of services as data layer of the application, because it’s usually here, where HTTP calls for data are made.

Since we are using Ionic, many of AngularJS’s builtin services are available to us. An example of this is the $http service which is used to make HTTP requests to servers. We will make use of this service in our Authentication service below.

Authentication Service

The service.js file will contain most of our apps’s logic. Our authentication service will be composed of 3 main functions: registerlogin, and logout. It will return these three functions and the value of the IsAuth variable. IsAuth is a boolean that is set to true if the user is already authenticated and false otherwise. The service.js also contains a factory which we will use to intercept all our HTTP requests. More on this later.

serviceskeleton

Promises

Before we start coding our service, lets talk about promises. When we make a HTTP request to our API, the time to complete the call will vary and may hold up our app waiting for a response which can be undesirable. We will be utilizing promises specifically Angular’s $q service to run our functions asynchronously. Once the call is completed, we can return and use the ‘promised’  value. A promise has three possible states: fulfilled, rejected, or pending. If the promise is resolved successfully, then it’s fulfilled. Otherwise, if the promise is resolved unsuccessfully, then it’s rejected. For our purposes, we are interested in the fulfilled and rejected state as our app will handle the behavior of each differently.

Register

We will be using Angular’s $http service which allows us to communicate with our backend using HTTP requests. We make a POST request with the user object which contains the username and password. The backend will check the username to make sure it doesn’t already exist. It will return a response.data object letting us know if the account creation was successful. We will look at the success property of the object and either resolve or reject the promise with the message contained in the text property.

serregister

Login

The login function is similar to our register function in that we use $http to make a POST request with the user object and wait for the ‘promised’ response. On success, we set the isAuth to true and store the returned JWT value. The most important part of the function is assigning the JWT to the Authorization part of the header which will be used with all member only requests.

serlogin

Logout

The logout function will set isAuth to false and the JWT_key to undefined, and $http.defaults.headers.common.Authorization to undefined.

serlogout

Interceptor

An interceptor is just a normal service factory that is added to the interceptors array. We want to create an interceptor to capture responses from our backend and modify our app’s behavior depending on the server’s response.

For our app, we are interested if our backend returns a 401, meaning our user is not authenticated and should not have access to the member only area. If a 401 is detected, we will $broadcast an Unauthenticated event on the $rootScope and then immediately use $q.reject() to reject the promise made by the $http service. Our main app controller will listen for the broadcast event and will navigate the user to the login page. We will write the code for this controller in the next section.

serinterceptor

After defining our interceptor, we can apply it to our app by pushing it into the $httpProvider.interceptors array.

<BACK | NEXT>