This article is part 3 of the SitePoint Angular 2 Tutorial on how to create a CRUD App with the Angular CLI. In this article, we’ll update our application to communicate with a REST API back end.
Prefer to learn Angular using a step-by-step video course? Check out Learn Angular 5 on SitePoint Premium.In part one we learned how to get our Todo application up and running and deploy it to GitHub pages. This worked just fine but, unfortunately, the whole app was crammed into a single component.
In part two we examined a more modular component architecture and learned how to break this single component into a structured tree of smaller components that are easier to understand, re-use and maintain.
You don’t need to have followed parts one and two of this tutorial for three to make sense. You can simply grab a copy of our repo, checkout the code from part two, and use that as a starting point. This is explained in more detail below.
Here’s what our application architecture looked like at the end of part 2:
Currently, the TodoDataService stores all data in memory. In this third article, we’ll update our application to communicate with a REST API back end instead.
We will:
By the end of this article, you’ll understand:
So, let’s get started!
Make sure you have the latest version of the Angular CLI installed. If you don’t, you can install this with the following command:
<span>npm install -g @angular/cli@latest </span>
If you need to remove a previous version of the Angular CLI, you can:
npm uninstall -g @angular/cli angular-cli npm cache clean <span>npm install -g @angular/cli@latest </span>
After that, you’ll need a copy of the code from part two. This is available on GitHub. Each article in this series has a corresponding tag in the repository so you can switch back and forth between the different states of the application.
The code that we ended with in part two and that we start with in this article is tagged as part-2. The code that we end this article with is tagged as part-3.
You can think of tags like an alias to a specific commit id. You can switch between them using git checkout. You can read more on that here.
So, to get up and running (the latest version of the Angular CLI installed) we would do this:
<span>git clone git@github.com:sitepoint-editors/angular-todo-app.git </span><span>cd angular-todo-app </span><span>git checkout part-2 </span><span>npm install </span>ng serve
Then visit http://localhost:4200/. If all’s well, you should see the working Todo app.
Let’s use json-server to quickly set up a mock back end.
From the root of the application, run:
<span>npm install json-server --save </span>
Next, in the root directory of our application, create a file called db.json with the following contents:
<span>{ </span> <span>"todos": [ </span> <span>{ </span> <span>"id": 1, </span> <span>"title": "Read SitePoint article", </span> <span>"complete": false </span> <span>}, </span> <span>{ </span> <span>"id": 2, </span> <span>"title": "Clean inbox", </span> <span>"complete": false </span> <span>}, </span> <span>{ </span> <span>"id": 3, </span> <span>"title": "Make restaurant reservation", </span> <span>"complete": false </span> <span>} </span> <span>] </span><span>} </span>
Finally, add a script to package.json to start our back end:
<span>"scripts": { </span> <span>... </span> <span>"json-server": "json-server --watch db.json" </span><span>} </span>
We can now launch our REST API back end using:
<span>npm run json-server </span>
This should display the following:
<span>\{^_^}/ hi! </span> Loading db.json Done Resources http://localhost:3000/todos Home http://localhost:3000
That’s it! We now have a REST API back end listening on port 3000.
To verify that your back end is running as expected, you can navigate your browser to http://localhost:3000.
The following endpoints are supported:
So if you navigate your browser to http://localhost:3000/todos, you should see a JSON response with all todos from db.json.
To learn more about json-server, make sure to check out mock REST APIs using json-server.
Now that we have our back end in place, we must store its URL in our Angular application.
Ideally, we should be able to this:
Luckily, Angular CLI supports environments. By default, there are two environments: development and production, both with a corresponding environment file: src/environments/environment.ts and ‘src/environments/environment.prod.ts.
Let’s add our API URL to both files:
<span>npm install -g @angular/cli@latest </span>
npm uninstall -g @angular/cli angular-cli npm cache clean <span>npm install -g @angular/cli@latest </span>
This will later allow us to get the API URL from our environment in our Angular application by doing:
<span>git clone git@github.com:sitepoint-editors/angular-todo-app.git </span><span>cd angular-todo-app </span><span>git checkout part-2 </span><span>npm install </span>ng serve
When we run ng serve or ng build, Angular CLI uses the value specified in the development environment (src/environments/environment.ts).
But when we run ng serve --environment prod or ng build --environment prod, Angular CLI uses the value specified in src/environments/environment.prod.ts.
This is exactly what we need to use a different API URL for development and production, without having to change our code.
The application in this article series is not hosted in production, so we specify the same API URL in our development and production environment. This allows us to run ng serve --environment prod or ng build --environment prod locally to see if everything works as expected.
You can find the mapping between dev and prod and their corresponding environment files in .angular-cli.json:
<span>npm install json-server --save </span>
You can also create additional environments such as staging by adding a key:
<span>{ </span> <span>"todos": [ </span> <span>{ </span> <span>"id": 1, </span> <span>"title": "Read SitePoint article", </span> <span>"complete": false </span> <span>}, </span> <span>{ </span> <span>"id": 2, </span> <span>"title": "Clean inbox", </span> <span>"complete": false </span> <span>}, </span> <span>{ </span> <span>"id": 3, </span> <span>"title": "Make restaurant reservation", </span> <span>"complete": false </span> <span>} </span> <span>] </span><span>} </span>
and creating the corresponding environment file.
To learn more about Angular CLI environments, make sure to check out the The Ultimate Angular CLI Reference Guide.
Now that we have our API URL stored in our environment, we can create an Angular service to communicate with the REST API back end.
Let’s use Angular CLI to create an ApiService to communicate with our REST API back end:
<span>"scripts": { </span> <span>... </span> <span>"json-server": "json-server --watch db.json" </span><span>} </span>
This gives the following output:
<span>npm install -g @angular/cli@latest </span>
The --module app.module.ts option tells Angular CLI to not only create the service but to also register it as a provider in the Angular module defined in app.module.ts.
Let’s open src/app/api.service.ts:
npm uninstall -g @angular/cli angular-cli npm cache clean <span>npm install -g @angular/cli@latest </span>
Next, we inject our environment and Angular’s built-in HTTP service:
<span>git clone git@github.com:sitepoint-editors/angular-todo-app.git </span><span>cd angular-todo-app </span><span>git checkout part-2 </span><span>npm install </span>ng serve
Before we implement the methods we need, let’s have a look at Angular’s HTTP service.
If you’re unfamiliar with the syntax, why not buy our Premium course, Introducing TypeScript.
The Angular HTTP service is available as an injectable class from @angular/http.
It’s built on top of XHR/JSONP and provides us with an HTTP client that we can use to make HTTP requests from within our Angular application.
The following methods are available to perform HTTP requests:
Each of these methods returns an RxJS Observable.
In contrast to the AngularJS 1.x HTTP service methods, which returned promises, the Angular HTTP service methods return Observables.
Don’t worry if you aren’t familiar yet with RxJS Observables. We only need the basics to get our application up and running. You can gradually learn more about the available operators when your application requires them and the ReactiveX website offers fantastic documentation.
If you want to learn more about Observables, it may also be worth checking out SitePoint’s Introduction to Functional Reactive Programming with RxJS.
If we think back of the endpoints our REST API back end exposes:
GET /todos: get all existing todos
GET /todos/:id: get an existing todo
POST /todos: create a new todo
PUT /todos/:id: update an existing todo
DELETE /todos/:id: delete an existing todo
we can already create a rough outline of methods we need and their corresponding Angular HTTP methods:
<span>npm install json-server --save </span>
Let’s have a closer look at each of the methods.
The getAllTodos() method allows us to get all todos from the API:
<span>{ </span> <span>"todos": [ </span> <span>{ </span> <span>"id": 1, </span> <span>"title": "Read SitePoint article", </span> <span>"complete": false </span> <span>}, </span> <span>{ </span> <span>"id": 2, </span> <span>"title": "Clean inbox", </span> <span>"complete": false </span> <span>}, </span> <span>{ </span> <span>"id": 3, </span> <span>"title": "Make restaurant reservation", </span> <span>"complete": false </span> <span>} </span> <span>] </span><span>} </span>
First, we make a GET request to get all todos from our API:
<span>"scripts": { </span> <span>... </span> <span>"json-server": "json-server --watch db.json" </span><span>} </span>
This returns an Observable.
We then call the map() method on the Observable to transform the the response from the API into an array of Todo objects:
<span>npm install -g @angular/cli@latest </span>
The incoming HTTP response is a string, so we first call response.json() to parse the JSON string to its corresponding JavaScript value.
We then loop over the todos of the API response and return an array of Todo instances. Note that this second use of map() is using Array.prototype.map(), not the RxJS operator.
Finally, we attach an error handler to log potential errors to the console:
npm uninstall -g @angular/cli angular-cli npm cache clean <span>npm install -g @angular/cli@latest </span>
We define the error handler in a separate method so we can reuse it in other methods:
<span>git clone git@github.com:sitepoint-editors/angular-todo-app.git </span><span>cd angular-todo-app </span><span>git checkout part-2 </span><span>npm install </span>ng serve
Before we can run this code, we must import the necessary dependencies from the RxJS library:
<span>npm install json-server --save </span>
Note that the RxJS library is huge. Instead of importing the entire RxJS library using import * as Rx from 'rxjs/Rx', it’s recommended to only import the pieces you require. This will substantially reduce the size of your resulting code bundle to a minimum.
In our application we import the Observable class:
<span>{ </span> <span>"todos": [ </span> <span>{ </span> <span>"id": 1, </span> <span>"title": "Read SitePoint article", </span> <span>"complete": false </span> <span>}, </span> <span>{ </span> <span>"id": 2, </span> <span>"title": "Clean inbox", </span> <span>"complete": false </span> <span>}, </span> <span>{ </span> <span>"id": 3, </span> <span>"title": "Make restaurant reservation", </span> <span>"complete": false </span> <span>} </span> <span>] </span><span>} </span>
We import the three operators that our code requires:
<span>"scripts": { </span> <span>... </span> <span>"json-server": "json-server --watch db.json" </span><span>} </span>
Importing operators ensures that our Observable instances have the corresponding methods attached to them.
If we do not have import 'rxjs/add/operator/map' in our code, then the following would not work:
<span>npm run json-server </span>
This is because the Observable returned by this.http.get would not have a map() method.
We only have to import the operators once to enable the corresponding Observable methods globally in your application. However, importing them more than once isn’t a problem and won’t increase the resulting bundle size.
The getTodoById() method allows us to get a single todo:
<span>\{^_^}/ hi! </span> Loading db.json Done Resources http://localhost:3000/todos Home http://localhost:3000
We don’t need this method in our application, but it’s included to give you an idea of what it would look like.
The createTodo() method allows us to create a new todo:
<span>// src/environments/environment.ts </span><span>// used when we run `ng serve` or `ng build` </span><span>export const environment = { </span> production<span>: false, </span> <span>// URL of development API </span> apiUrl<span>: 'http://localhost:3000' </span><span>}; </span>
We first perform a POST request to our API and pass in the data as the second argument:
<span>// src/environments/environment.prod.ts </span><span>// used when we run `ng serve --environment prod` or `ng build --environment prod` </span><span>export const environment = { </span> production<span>: true, </span> <span>// URL of production API </span> apiUrl<span>: 'http://localhost:3000' </span><span>}; </span>
We then transform the response into a Todo object:
<span>import { environment } from 'environments/environment'; </span> <span>// we can now access environment.apiUrl </span><span>const API_URL = environment.apiUrl; </span>
The updateTodo() method allows us to update a single todo:
<span>"environments": { </span> <span>"dev": "environments/environment.ts", </span> <span>"prod": "environments/environment.prod.ts" </span><span>} </span>
We first perform a PUT request to our API and pass in the data as the second argument:
<span>"environments": { </span> <span>"dev": "environments/environment.ts", </span> <span>"staging": "environments/environment.staging.ts", </span> <span>"prod": "environments/environment.prod.ts" </span><span>} </span>
We then transform the response into a Todo object:
ng generate <span>service Api --module app.module.ts </span>
The deleteTodoById() method allows us to delete a single todo:
installing <span>service </span> create src/app/api.service.spec.ts create src/app/api.service.ts update src/app/app.module.ts
We first perform a DELETE request to our API:
<span>import { Injectable } from '@angular/core'; </span> <span><span>@Injectable</span>() </span><span>export class ApiService { </span> <span>constructor() { } </span> <span>} </span>
We then transform the response into null:
<span>import { Injectable } from '@angular/core'; </span><span>import { environment } from 'environments/environment'; </span><span>import { Http } from '@angular/http'; </span> <span>const API_URL = environment.apiUrl; </span> <span><span>@Injectable</span>() </span><span>export class ApiService { </span> <span>constructor( </span> <span>private http: Http </span> <span>) { </span> <span>} </span> <span>} </span>
We don’t really need to transform the response here and could leave out this line. It’s just included to give you an idea of how you could process the response if you API would return data when you perform a DELETE request.
Here’s the complete code for our ApiService:
<span>npm install -g @angular/cli@latest </span>
Now that we have our ApiService in place, we can use it to let our TodoDataService communicate with our REST API back end.
Currently our TodoDataService stores all data in memory:
npm uninstall -g @angular/cli angular-cli npm cache clean <span>npm install -g @angular/cli@latest </span>
To let our TodoDataService communicate with our REST API back end, we must inject our new ApiService:
<span>git clone git@github.com:sitepoint-editors/angular-todo-app.git </span><span>cd angular-todo-app </span><span>git checkout part-2 </span><span>npm install </span>ng serve
We also update its methods to delegate all work to the corresponding methods in the ApiService:
<span>npm install json-server --save </span>
Our new method implementations look a lot simpler because the data logic is now handled by the REST API back end.
However, there’s an important difference. The old methods contained synchronous code and immediately returned a value. The updated methods contain asynchronous code and return an Observable.
This means we also have to update the code that is calling the TodoDataService methods to handle Observables correctly.
Currently, the AppComponent expects the TodoDataService to directly return JavaScript objects and arrays:
<span>{ </span> <span>"todos": [ </span> <span>{ </span> <span>"id": 1, </span> <span>"title": "Read SitePoint article", </span> <span>"complete": false </span> <span>}, </span> <span>{ </span> <span>"id": 2, </span> <span>"title": "Clean inbox", </span> <span>"complete": false </span> <span>}, </span> <span>{ </span> <span>"id": 3, </span> <span>"title": "Make restaurant reservation", </span> <span>"complete": false </span> <span>} </span> <span>] </span><span>} </span>
But our new ApiService methods return Observables.
Similar to Promises, Observables are asynchronous in nature, so we have to update the code to handle the Observable responses accordingly:
If we currently call the TodoDataService.getAllTodos() method in get todos():
<span>"scripts": { </span> <span>... </span> <span>"json-server": "json-server --watch db.json" </span><span>} </span>
the TodoDataService.getAllTodos() method calls the corresponding ApiService.getAllTodos() method:
<span>npm run json-server </span>
This, in turn, instructs the Angular HTTP service to perform an HTTP GET request:
<span>\{^_^}/ hi! </span> Loading db.json Done Resources http://localhost:3000/todos Home http://localhost:3000
However, there’s one important thing we have to remember!
As long as we don’t subscribe to the Observable returned by:
<span>// src/environments/environment.ts </span><span>// used when we run `ng serve` or `ng build` </span><span>export const environment = { </span> production<span>: false, </span> <span>// URL of development API </span> apiUrl<span>: 'http://localhost:3000' </span><span>}; </span>
no actual HTTP request is made.
To subscribe to an Observable, we can use the subscribe() method, which takes three arguments:
Let’s rewrite our current code:
<span>// src/environments/environment.prod.ts </span><span>// used when we run `ng serve --environment prod` or `ng build --environment prod` </span><span>export const environment = { </span> production<span>: true, </span> <span>// URL of production API </span> apiUrl<span>: 'http://localhost:3000' </span><span>}; </span>
This will load the todos asynchronously when the AppComponent is initialized:
<span>import { environment } from 'environments/environment'; </span> <span>// we can now access environment.apiUrl </span><span>const API_URL = environment.apiUrl; </span>
First, we define a public property, todos, and set its initial value to an empty array.
We then use the ngOnInit() method to subscribe to this.todoDataService.getAllTodos(), and when a value comes in, we assign it to this.todos, overwriting its initial value of an empty array.
Now let’s update the onAddTodo(todo) method to also handle an Observable response:
<span>"environments": { </span> <span>"dev": "environments/environment.ts", </span> <span>"prod": "environments/environment.prod.ts" </span><span>} </span>
Again, we use the subscribe() method to subscribe to the Observable returned by this.todoDataService.addTodo(todo), and when the response comes in, we add the newly created todo to the current list of todos.
We repeat the same exercise for the other methods until our AppComponent looks like this:
<span>npm install -g @angular/cli@latest </span>
That’s it; all methods are now capable of handling Observables returned by the TodoDataService methods.
Notice that there’s no need to unsubscribe manually when you subscribe to an Observable that’s returned by the Angular HTTP service. Angular will clean up everything for you to prevent memory leaks.
Let’s see if everything’s working as expected.
Open a terminal window.
From the root of our application directory, start the REST API back end:
npm uninstall -g @angular/cli angular-cli npm cache clean <span>npm install -g @angular/cli@latest </span>
Open a second terminal window.
Again, from the root of our application directory, serve the Angular application:
<span>git clone git@github.com:sitepoint-editors/angular-todo-app.git </span><span>cd angular-todo-app </span><span>git checkout part-2 </span><span>npm install </span>ng serve
Now, navigate your browser to http://localhost:4200.
If all goes well, you should see this:
If you see an error, you can compare your code to the working version on GitHub.
Awesome! Our application is now communicating with the REST API back end!
Side tip: if you want to run npm run json-server and ng serve in the same terminal, you can use concurrently to run both commands concurrently without opening multiple terminal windows or tabs.
Let’s run our unit tests to verify that everything’s working as expected.
Open a third terminal window.
Again, from the root of your application directory, run the unit tests:
<span>npm install json-server --save </span>
It seems that 11 unit tests are failing:
Let’s see why our tests are failing and how we can fix them.
First, let’s open up src/todo-data.service.spec.ts:
<span>{ </span> <span>"todos": [ </span> <span>{ </span> <span>"id": 1, </span> <span>"title": "Read SitePoint article", </span> <span>"complete": false </span> <span>}, </span> <span>{ </span> <span>"id": 2, </span> <span>"title": "Clean inbox", </span> <span>"complete": false </span> <span>}, </span> <span>{ </span> <span>"id": 3, </span> <span>"title": "Make restaurant reservation", </span> <span>"complete": false </span> <span>} </span> <span>] </span><span>} </span>
Most of the failing unit tests are concerned with checking data handling. These tests are no longer required because data handling is now performed by our REST API back end instead of the TodoDataService, so let’s remove the obsolete tests:
<span>"scripts": { </span> <span>... </span> <span>"json-server": "json-server --watch db.json" </span><span>} </span>
If we now run the unit tests, we get an error:
<span>npm run json-server </span>
The error is thrown because TestBed.configureTestingModule() creates a temporary module for testing and the injector of the temporary module is not aware of any ApiService.
To make the injector aware of the ApiService, we have to register it with the temporary module by listing ApiService as a provider in the configuration object that is passed to TestBed.configureTestingModule():
<span>\{^_^}/ hi! </span> Loading db.json Done Resources http://localhost:3000/todos Home http://localhost:3000
However, if we do this, our unit test will use our real ApiService, which connects to our REST API back end.
We don’t want our test runner to connect to a real API when running our unit tests, so let’s create an ApiMockService to mock the real ApiService in unit tests.
Let’s use Angular CLI to generate a new ApiMockService:
<span>npm install -g @angular/cli@latest </span>
This shows the following:
npm uninstall -g @angular/cli angular-cli npm cache clean <span>npm install -g @angular/cli@latest </span>
Next, we implement the same methods as ApiService, but we let the methods return mock data instead of making HTTP requests:
<span>git clone git@github.com:sitepoint-editors/angular-todo-app.git </span><span>cd angular-todo-app </span><span>git checkout part-2 </span><span>npm install </span>ng serve
Notice how each method returns fresh new mock data. This may seem a bit repetitive, but it’s a good practice. If one unit test would change mock data, the change can never affect the data in another unit test.
Now that we have an ApiMockService service, we can substitute ApiService in our unit tests with ApiMockService.
Let’s open up src/todo-data.service.spec.ts again.
In the providers array, we tell the injector to provide the ApiMockService whenever the ApiService is requested:
<span>npm install json-server --save </span>
If we now re-run the unit tests, the error is gone. Great!
We still have two more failing tests, though:
<span>{ </span> <span>"todos": [ </span> <span>{ </span> <span>"id": 1, </span> <span>"title": "Read SitePoint article", </span> <span>"complete": false </span> <span>}, </span> <span>{ </span> <span>"id": 2, </span> <span>"title": "Clean inbox", </span> <span>"complete": false </span> <span>}, </span> <span>{ </span> <span>"id": 3, </span> <span>"title": "Make restaurant reservation", </span> <span>"complete": false </span> <span>} </span> <span>] </span><span>} </span>
The errors are similar to the one we just fixed.
To fix the first error, let’s open src/api.service.spec.ts:
<span>"scripts": { </span> <span>... </span> <span>"json-server": "json-server --watch db.json" </span><span>} </span>
The test fails with a message No provider for Http!, indicating that we need to add a provider for Http.
Again, we don’t want the Http service to send out real HTTP requests, so we instantiate a mock Http service that uses Angular’s MockBackend:
<span>npm run json-server </span>
Don’t worry if configuring the test module looks a bit overwhelming.
You can learn more about setting up unit test in the official documentation for testing Angular applications.
To fix the final error:
<span>\{^_^}/ hi! </span> Loading db.json Done Resources http://localhost:3000/todos Home http://localhost:3000
let’s open up src/app.component.spec.ts:
<span>// src/environments/environment.ts </span><span>// used when we run `ng serve` or `ng build` </span><span>export const environment = { </span> production<span>: false, </span> <span>// URL of development API </span> apiUrl<span>: 'http://localhost:3000' </span><span>}; </span>
Then provide the injector with our mock ApiService:
<span>// src/environments/environment.prod.ts </span><span>// used when we run `ng serve --environment prod` or `ng build --environment prod` </span><span>export const environment = { </span> production<span>: true, </span> <span>// URL of production API </span> apiUrl<span>: 'http://localhost:3000' </span><span>}; </span>
Hurray! All our tests are passing:
We have successfully connected our Angular application to our REST API back end.
To deploy our application to a production environment, we can now run:
<span>import { environment } from 'environments/environment'; </span> <span>// we can now access environment.apiUrl </span><span>const API_URL = environment.apiUrl; </span>
We also upload the generated dist directory to our hosting server. How sweet is that?
Let’s recap what we’ve learned.
In the first article, we learned how to:
In the second article, we refactored AppComponent to delegate most of its work to:
In this third article, we:
In the process, we learned:
All code from this article is available on GitHub.
In part four, we’ll introduce the router and refactor AppComponent to use the router to fetch the todos from the back end.
In part five, we’ll implement authentication to prevent unauthorized access to our application.
This article was peer reviewed by Vildan Softic. Thanks to all of SitePoint’s peer reviewers for making SitePoint content the best it can be!
RxJS, short for Reactive Extensions for JavaScript, is a library for reactive programming that uses Observables, to make it easier to compose asynchronous or callback-based code. In the context of Angular API service, RxJS plays a crucial role in handling asynchronous operations. It provides a way to create and work with observables that makes it possible to manage multiple asynchronous operations, handle errors, and even cancel operations. This makes it a powerful tool for working with HTTP requests, which are inherently asynchronous.
Angular interacts with a REST backend through the HttpClient module. This module provides a simplified API for HTTP functionality. It allows Angular to make HTTP requests to the server, send user data, or retrieve data from the server. The HttpClient module also includes methods for requests such as GET, POST, PUT, DELETE, which correspond to the HTTP methods used in RESTful APIs.
Error handling is an essential part of any application. In Angular API service, you can handle errors using the catchError operator from RxJS. This operator catches the error on the Observable, and allows you to handle it or return a new Observable. You can use it in the pipe method of the Observable, after the method that might throw an error.
In Angular API service, you can cancel a request using the unsubscribe method of the Subscription object. When you subscribe to an Observable, it returns a Subscription object. This object has an unsubscribe method that you can call to cancel the subscription, and consequently, the HTTP request.
In Angular API service, you can retry a failed request using the retry or retryWhen operators from RxJS. The retry operator resubscribes to the Observable, effectively repeating the HTTP request. The retryWhen operator allows you to define a condition for retrying the request.
In Angular API service, you can make multiple requests using the forkJoin function from RxJS. This function takes an array of Observables and returns a new Observable that emits an array of the results of the input Observables, once they all complete.
In Angular API service, you can transform the response data using the map operator from RxJS. This operator applies a given function to each item emitted by the Observable, and returns a new Observable that emits the results.
In Angular API service, you can send data to the server using the post method of the HttpClient module. This method takes the URL of the server and the data to send as parameters, and returns an Observable that you can subscribe to.
In Angular API service, you can update data on the server using the put method of the HttpClient module. This method takes the URL of the server, the data to update, and optionally, the options for the request as parameters, and returns an Observable that you can subscribe to.
In Angular API service, you can delete data from the server using the delete method of the HttpClient module. This method takes the URL of the server and optionally, the options for the request as parameters, and returns an Observable that you can subscribe to.
The above is the detailed content of Angular and RxJS: Adding a REST API Back End. For more information, please follow other related articles on the PHP Chinese website!