In some cases your application might need to upload large amounts of data, such as files. Obviously for a good UX we should provide the user some feedback on the progress of the upload. Angular’s
HttpRequest object has a property
reportProgress which allows us to do exactly that. Let’s see how.
In the background here, we have a Node JS server which listens at this endpoint for allowing us to upload some files because we want to try and see how we can use the HTTP client to basically upload some file and listen to the upload events while the file is being uploaded.
Let's switch to the app component HTML and start here by creating an input of type file which will serve us as the upload control of course. Then we have a button which user can click to actually trigger upload.
Here on the click handler, we say upload avatar. We want to pass here directly that file upload into that method. In this way, we basically pass the underlying object here to our method, upload avatar, which we create here on our component, which allows us now to access basically the API of that underlying input type file.
To guard the data, we need to create here of some form data. Create here a form data object, and we use that API which has an append method. Let's call it avatar. Then we access here the file upload.files API, and we grab the first file.
Now, as you can see, we could have here multiple files, but in our example, we just have one so we can safely access the first. Let's give it a name, avatar.jpeg. This is the data which we want to send to the backend. The actual sending takes place in this people service because we want to abstract this sending from the actual presentation logic, so here we create an upload avatar function as well.
We will get here the data which gets passed in this parameter. Now inside here, we will use that HTTP client which as you can see I have already imported from the common HTTP, and it gets injected here in my function.
First of all, let's create a request object. Here we use the HTTP request object which we also need to import from the Angular common HTTP. This gets a series of parameters. First of all, the method so the HTTP verb which in this case is clearly opposed. Then we get to define URL which is here the same one where our server listens. Let's paste this in here.
We pass in the data which we get as a parameter here. Finally comes the important part which is the report progress property which we set to true. This one will actually allow us to listen to these events.
Now we need to invoke that HTTP request by using the HTTP object and using the request function here and passing in that request object. All of this needs to be returned. As a return time here, we get an observable of type HTTP event of type object.
Again, we need to import that from the Angular common HTTP as well. Great. The upload avatar function here in our people service looks quite finished. Let's jump back to the component here.
Now we can use it. We can say this.people service.upload avatar. We pass in the form data. We can then subscribe here to that observable. In the subscribe callback here, we get an object which we call here response. This object will have different kind of types.
While we are uploading, we can check the type and whether it is of HTTP event type.upload progress. We need to import that. Whenever this basically of type upload progress, we can use the variable here above which I've created before to modify the user.
We can here do some percentage calculations. We could say const percentage equals math.round. Let's do some math here. We say response. Here we see we have some handy properties. We say the loaded divided by the total one. This will give us the percentage. Now, we can say file is dollar percentage percent uploaded.
Instead in the other case, else if, the response is an instance of an HTTP response object which again we need to import up there. Then we have basically finished that upload, so we can say file is completely uploaded.
Now, let's choose a file here. I take a large one, so let's do the type check which is a video. I click upload, and you can see here some progress being shown and then the file is completely uploaded. Since I'm here at the local environment and obviously I'm uploading to a local web server, that goes quite fast.
We can open here the dev tools and throttle basically the network connection to a 4G, 3G connection. Now let's again upload. Now we can see how that upload percentage is being updated.
Again, if we set the online again, it goes fast and completes successfully.