Find out how to write custom services for your Angular 2 application to make working with server requests much easier as your application grows.
- [Instructor] Lets move our rest requests into a custom service. Custom services make adding and updating requests much easier as our application grows, because the service can be used across multiple components, with all changes taking place at the service level instead of each individual component. We'll start by creating a new file in the shared folder, in our application. You can call this new file whatever you'd like. I'll call mine, "rest request", and we'll follow Angular's file naming conventions of rest-request.service.ts.
All Angular services must be declared as injectable, using the injectable decorator, imported from the Angular core module. We'll do that in our file, by creating new import statement and between the brackets, importing, "Injectable from @angular/core". We'll declare this file as injectable, by typing, "@Injectable", followed by opening and closing parentheses. We'll then export a class, following the naming convention we used throughout the application.
A custom namespace of "Xyz", followed by the name of our service, "RestRequestService". Each method in this new service, will return an observable we can subscribe to in the component. Returning observables is one of many design patterns we could use to build this service, and I encourage you to experiment with different patterns to find one that works best for your specific needs. Just like earlier in this course, we'll need to import the HTTP and JSONP classes, so we can communicate with our server.
We do that by creating a new import statement and importing, "http" and "Jsonp from @angular/http". We'll also need instance variables declared on our constructor. We do this by creating new private properties and assigning them to their classes.
Our server has endpoints for user settings and user locations. So, we'll create properties for each of these URLs and copy the existing values from the component, into our service. We'll declare a "settingsUrl", as well as a "locationsUrl". Back in the component, we'll copy the URL for user settings and we'll copy the URL for user locations.
We'll also declare these properties at the top of our class. Both properties, will be declared as "strings". We'll then create methods to get data from each of these endpoints. We'll have a "getSettings" method and a "getLocations" method. And we'll place our service requests, inside these methods. Back in the user list, we'll copy our jsonp.get request Copy, paste.
And we'll copy our HTTP GET request for the locations. We'll place the appropriate server request, inside its method. We'll also return each of these server requests. Returning these requests is what allows us to subscribe to the response objects in the component. Back in the component, we'll import our new rest request service, add it to the array of providers in our component decorator, and instantiate the service in our constructor.
We do this by creating a new import statement at the top of the file, and importing, "XyzRestRequestService "from ../shared/rest-request.service". In our component decorator, we'll add this new class to the list of providers and in our constructor, we'll create a new private variable called, "xyzRestRequestService:" and assign it to the "XyzRestRequestService" class.
In the ngOnInit method, we'll replace the existing rest requests with calls to our new service methods. The JSONP request is replaced by "this.xyzRestRequestService.getSettings", and the HTTP GET request is replaced by "this.xyzRestRequestService.getLocations". We don't have to pass anything into these methods.
Back in the browser, we see our user list loads, as expected. We'll add one more method to our rest service, called "setSettings". This will allow us to update the user settings on the server. This method will take one argument, an object containing the payload, we're sending back to the server. I'll call the argument, "payload" and I'll assign it to type, "Object". We'll send this data to the server, using an HTTP PUT request, just like we did in our component earlier in the course.
We'll go back to our component, we'll scroll down to the "onFilter" method, and we'll copy the HTTP PUT request from there into our new "setSettings" method; passing in the payload, as the second argument. We'll return this server request, as well. Returning the server request allows us to subscribe to the response object in our component, just like we do with the "getSettings" and "getLocations" methods.
Back in the component, we'll replace the server requests in our "onFilter" and "onClear" methods with calls to our new "setSettings" method. We will delete "this.http.put" and replace it with, "this.xyzRestRequestService.setSettings". Since the URL is already in our service, we can remove the reference to the settings URL and pass-in just the payload object.
We'll do the same in the "onClear" method, removing "this.http.put", and replacing it with "this.xyzRestRequestService.setSettings", and passing in just the payload. We no longer need to import the HTTP and JSONP classes into this component. So, we'll remove the import statement from the top of this file, as well as any references to their instances, in addition to any references to the server URLs.
Back in the browser, our application still works as expected.
- Overview of data storage options
- Saving and retrieving data from the browser
- Setting routes in the URL
- Using query strings and fragments instead of routes
- Saving and retrieving data from a server
- Working with user input
- Using JSONP instead of HTTP
- Why writing custom services is important
- Writing custom services for working with browsers and servers