Upload and Download Files with Progress | Spring Boot and Angular

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this tutorial i'm going to show you how you can use spring boot in angular to upload and download files i have the application that we're going to be building running and it's running on my local computer as you can see here and it's a fairly simple application where a user can come in and they can upload and download files and i'm gonna go ahead and just click on choose file here which is the button where we can click to choose the files and then upload the files so i'm gonna go ahead and click choose files and i have this list of files here and those are like videos that i have created for a course and i'm gonna upload one of those files you can upload one file or you can upload multiple files so here i'm just gonna select one file and you can see there was a progress bar that just happened here and it was really fast and we didn't get to see it but you can see that the file has been processed and now i have the file here and if i need to download the file from the server i can also do that so i can just go ahead and click on this download here and you can see i can go ahead and download the file and i can just save it and you can see the file is downloaded down here another thing i'm going to be showing you is how to display the upload and download progress which is something you usually want to show a user whenever they're like uploading or downloading some very large file you know to a remote server so if i go ahead and click choose files again and you can see all my files they're sorted by size so i'm going to scroll down and pick like a very large file for instance this one you can see now we have the progress bar and we can monitor the progress of this file being uploaded to the server and you can see now it's done and the same thing will happen if i try to download the file and if i click on download here you can see the file that's being downloaded once it's done then i'm presented to save the file and i can just choose the location and then save the file and we're going to be using angular with spring boot and the back end to do all of that and we're not going to be using any libraries or anything like that we're just going to be using typescript javascript and using stringboot for the backend so if i open the developer tool here just want to show you because i have some logs going on and if i try to upload something again i'm going to go ahead and see if i can find a bigger file so let's say this one you can see that all the events are being printed here on the console as the file is being uploaded once the file is done then we get the response from the server and the same thing again is going to happen so if i try to download you can see that we're downloading the file on this server and then we're presented to save the file here and i can go ahead and save the file if i want to and like i said we can select multiple files so i can click here and then i'm going to press shift and select those files and click upload and you can see that it's taking a little bit longer because i have more files and it's done you can see all the files are here and i can of course download any of those files so that's what i'm going to be showing you um it's a very simple application however the functionalities that you're going to learn here they're going to be very useful because this is the same logic that is used every time you're trying to upload and download file and you want to show something to the user so that you can show them that the progress is being made then you can use that in any application that you have so i'm going to give you a quick overview of how this whole work with http in the back end in the front end and then we're going to dive right into the code so i want to give you a quick overview of what's going on here before we actually dive into the code right so we have a client and that client is what needs to communicate with another computer somewhere and we're going to call that other computer server the client can be a server and the server can be a client and the only way you're going to be able to make a distinction is by looking at the computer that is initiating the request the computer that is initiating the request is the client and the computer that is always running usually always running and it's waiting to be connected that computer is the server it can be vice versa depends on the way you look at it but the client is the computer that is initiating the connection and the server is another computer somewhere on the internet or in your network on a separate network and it's just waiting to be connected by some other computer so we have our client and then we have our server and we want to take a file from the client and then send that file over to the server and this is something that happens all the time so if you on the internet you download some files you're on google drive and you upload some file you're doing exactly the same thing so your computer is the client and the google computer on some google's data centers is just gonna be the server because you're trying to upload files there of course it's a little bit more complicated than that but at a high level that's the idea your client is your computer and then you want that computer to take a file and then upload it to google's computer so that you can save your file there and the way we're going to do this is by using the http protocol so we're going to have http running on the client and then hdb also running on the server now http is using a different protocol under the hood and that's tcp ip so tcp is what's going to actually initiate the connection from the client to the server so whenever you want to transfer the file tcp is going to open a connection on a socket on your computer and then it's going to use the ip address of the other computer and try to open a connection with that computer on some socket on that computer so since we're using http so that's usually port 80 or 443 if we're using secret socket but in this case we're not so that's probably going to be port 80 or it can be any port that you specify depending on you know what type of application you're building but for http it's usually port 80. so tcp is what is actually going to create the connection now uh there's a lot more that we can say about tcp slash ip they can be pretty complicated but we don't want to go into all the details so tcp is going to create the connection um on two sockets on those two computers and i'm just going to represent this channel that is going to be created in yellow here now what's going to happen is whenever we need to transfer the file tcp is going to take that file and then chop it up into chunks and then create packets and put those chunks into packets and then send them from the client to the server so instead of sending the entire file unless the file is really small tcp is never going to try to transmit the entire file from the client to the server what it's going to do is it's going to chop up the file into small chunks and then send those chunks one by one over to the server so that the server can put all those chunks together and then reconstruct the file itself and this is where our progress comes into play because as tcp is chopping up the file into small chunks and then sending all those chunks we can actually have some monitoring going on what tcp is telling us how much of this data is being uploaded and how much is left to be uploaded to the server and we can use that to determine the progress of the file being uploaded from the client to the server now once the entire file gets to the server the server is then gonna you know put this file together and then save it somewhere on the server so that's the processing of the server but what we're really doing when we're showing the progress we're showing the file or the chunks of the file being transferred over the network wire by tcp bit by bit so this is really what's going on under the hood at a high level again this is really way more complicated than that but we don't want to get into all the details but that's what's going on under the hood whenever we try to use http which is an application layer protocol and it used tcp slash ip under the hood to create the connection and then transfer the file i'm on this spring initializer website and i'm going to go ahead and create a spring boot application i've already filled in the information about the application so the group and artifact id the name of the application i give a little bit of a description as you can see here and then i give the package that i want and i'm going to be using a jar for my packaging but we probably won't need this because i'm not going to be deploying the application and then i'm going to be using java 8 but you can choose java 11 16 war for your packaging whatever it will work for you whatever makes sense for you now the only dependency that we're going to need for this is going to be the web dependency so i'm going to click on add dependency i'm going to type web and i'm just going to pick the first one and that's the only dependency that we're going to need for this application because we're not doing much and i'm going to go ahead and click on generate here to generate this application all right i'm gonna go ahead and save it in my downloads folder all right and then i'm gonna go ahead and open this with intellij so i have the application open and intelligent and as you can see it's a very simple spring boot application and nothing special here so i'm going to go ahead and create a new package i'm going to right click here go to new and in package and i'm just going to call this package resource because that's where our controller is going to be and then i'm going to create a new file here and i'm going to call it file resource because this is our file resource like we're manipulating files somehow all right so the first thing i want to do is i want to annotate this class as a controller because this is going to be a rest controller so i'm going to do rest controller and it's right here and the second thing i want to do is i want to give this a path so i'm going to add request mapping and let's just say we're gonna map everything in this class to slash file okay so that's gonna be the root path for this file resource so i'm gonna go ahead and collapse this for now so what we wanna do is very simple so the first thing we want to do is we want to set a location so define a location so we need a place to save the file on the server so that's going to be the first thing we're going to do and then what we need to do next is define a function or well since we're in the backend now this is a method to upload files all right so that's the second thing we need to do and the third thing we have to do is to define a method to download files because that's what we're trying to do so let's go ahead and tackle the first requirement so what we want to do here is to find a location on the server so i'm going to do public static final string and i'm gonna call this directory so i'm gonna do directory so that's gonna be the folder where i'm gonna be saving all the files and then i'm gonna set this equal to oops system that get property and i want to get the the home directory of the currently logged in user and the way you do this is you do user.home so what this is going to return is whatever user is logged in it's going to give me the home directory of this user here when i call the system get property and i pass in the string user.home and then i want to navigate to my downloads folder so i'm going to do forward slash downloads and let's say i'm going to create a folder called uploads okay so all of the files that i'm going to be creating they're going to go inside that folder that i'm going to call uploads and that folder is going to leave in my downloads okay so this is the location where we're gonna save all the files as they're being uploaded and this can be anywhere you want so you can define this as a string you can use the system properties to get the currently logged in user location or the home of that user and then define whatever path you want i'm just trying to tell you that this is whatever you want it to be doesn't have to be exactly what i'm doing here i put this in my you know download so that i can delete them later because i don't need to keep those files as i show you how the application works now the second thing we have to do we have to define a method that's gonna go ahead and upload all the files so i'm gonna go down here and then i'm gonna do at post mapping because this is gonna accept the post request since we're trying to create some resource on the server in this case that's gonna be file and i want this to go to upload okay so that's gonna be forward slash upload so we're gonna go from file and then upload that's where we're gonna send all the requests to upload files now i'm gonna define this function so i'm gonna do public and this is gonna return a response entity and what i want this to return is a list of string okay so i'm gonna do list of string and the reason for this is because whenever the user or whoever is using the application whenever they upload a bunch of files or one file i want to return an array or in a list the names of the files that they have uploaded so that's why i'm returning a string a list of string here because i need those names so that whenever they try to download the files and i can look the file up in the back end which is in the server this application is running by referring to the name of the actual files so i'm going to return the list of the names of the files and then i'm just going to call this upload files and i'm going to pass it some parameters so what we want to do here we want to have a way to retrieve all the files that are being passed in this request and the way we can do this is by calling the request parameter so we're gonna do request param and then we're gonna be looking for a key called files okay so that's gonna be the key that they're gonna pass whenever they're uploading the files on the forum so if they have an input element they're gonna put the name of this input as files and you're gonna see how this is not gonna connect to the front end once we build the front end and then here we can just get all the multiple files that they're going to pass so here we're going to pass in a list and we're going to say this is going to be a list of multi-part files and we're just going to call those multipart files here so we're going to get all the files that's being passed to this function or to this method whenever they try to upload something so now once we have all those files then we can you know get the names of the files and then put them in a list return that list to the user and then save those files like the physical files on the server itself so what i want to do is i want to define a list and that's going to be a list of string and i'm going to call this file names and i'm going to declare this as a new arraylist so i'm gonna be using this list so that i can save all of the file names and then return them to the user and next i need a for loop so i'm gonna do four every multipat file that i'm gonna call here just file that i get from the list of all the files that i'm getting here so i can do something like this okay so we're gonna loop through and then multiply files okay so we're gonna look through all of the files and then we're gonna save them in this computer so i'm gonna scroll up a little bit so the first thing i wanna do is get the current file name so i'm gonna define a string here and i'm gonna call it file name and then i'm gonna set it equal to the file and the current iteration so i'm going to do multiply file well this is supposed to be file and get original file name and we can clean this up a little bit if we want so here i can do string util and it's coming from string that clean path okay so we can just clean this just to make sure all right so now we have the file name of the file in the current iteration now we need to define the directory so where we're gonna save the file so i'm gonna use the path for that so i'm gonna do path and i'm just gonna call this uh file storage oops and then use the get method to go ahead and pass in the uh location so here this is going to be the directory and i'm also going to pass in the file name and let's just call the to absolute and normalize that all right so this is going to give me the uh storage where i need to put the file which is this directory and then the file name is going to be this file name that we're passing in here so now that we have the file name we have the storage where we're going to put the file all we have to do now is to just copy the file in that location and to do this we can just call the copy and here we can pass in the input stream of the file so we can do file that get input stream and then we can pass in the location so we're going to do file storage and another thing i want to do is in case there is an existing file in that specific location with the same name i want to replace it if it already exists so i can do replace existing and all of these are coming from java and io so if i over over this you can see it's coming from java and io so the copy the get here coming from the same package so make sure you import those from the right place so now at this point here on line 40 the file has been saved in that location what we can do then is just put that file name in our file list so i can call the oops file names and i can just add this file into it so i can do file name okay so the file name of the file and the current iteration that we get here will create the storage so the location where we're going to save the file we save the file in that location and then we add this file name into the list of file so that we can return those file names in the body of the response so once we're done iterating as you can see here we can go down below here and then return response entity and i'm going to send an ok to the user and in embody of the response i'm going to pass in the list of all the files so i'm going to do file names and that's all we have to do so just to recap we're going to get all of the files coming from the request we're going to assign them to this list of multiplied files and then we're going to define a list of strings so that we can put all of the file names and then we're going to iterate or we're going to loop over every file that we receive from the user we're going to get the file name get the location and then copy this file in that location replacing any existing file if there is any existing file there and then we're going to add this file name into that list so that we can return it once once we're done looping here as a list of all the files or the name of the files that we saved so that we can use those name or those file names later to download the files and that's all we have to do for this so now let's go ahead and tackle our last requirement which is to download files whenever the user give us the file name so let's go ahead and scroll down a little bit so that we can start this method so the first thing we want we want to have a path for this so i'm gonna do at and this is going to do a get mapping because the user is trying to get information from the server and i'm going to map this to download and let's just say i need the file name so to get this i'm going to get this as a as a path variable so i'm gonna put file name here and i'm gonna do the body of the method so public and this is gonna return a response entity again and this time it's gonna be of type resource so i'm gonna type resource because we're trying to send the resource back to the user and make sure you import this from spring framework and i'm going to go ahead and call this function download files because that's what it's doing and to get this file name i'm going to get it as a path variable so i'm going to add path variable and then pass in the name so here the name is going to be filename which is the same name that we have here i'm going to copy this and pass it here and then i'm going to get this as a string and then just call it the same name so file name here and then we can start with the body of the method so the first thing i want to do with the file name is to find this file right so you can see here the same way that we get this storage and then we put this file in we need to be able to do something similar so that we can find this file on the system using the same directory so i'm gonna go down here and then define another path and i'm gonna call it file path and i'm going to call the get again and then i'm going to pass in the directory where everything is so directory and do to absolute path and normalize and then i wanted to resolve the actual file name so here i'm going to pass in the file name so this path is going to give us the entire path to the location of the file with the file name itself and then what i want to do just for sending it is to check if this file exists so here i'm gonna do if files oops exist so this is gonna check to see if the file exists in that path okay so if it exists it's gonna return true so in that case i'm gonna negate this with an exclamation mark and then here i'm going to say if the file doesn't exist then let's throw an exception so i'm going to throw a new file not found exception and that's coming from java file.io and i'm gonna pass the file name and then i'm gonna say this file was not found on the server something like that i mean this can be anything you want so in case we do find the file then we can continue we can skip this if statement and then continue now you have to understand that if this is true which means if we didn't find the file then the method execution is going to stop on line 53 because it's going to throw an exception here so then if the file exists then we can go ahead and continue so what i want to do is to create a resource so i'm going to resource and i'm going to call it resource and i'm going to call new url resource and then pass in the file path and here and do to uri so that way we get the resource that we create out of the path or the file resource that we have on the computer and we need to add this exception to this method so let's let's just make it through i o exception because that's going to cover everything and we need an equal sign here and then once we get this resource we need to send a content deposition as the headers and then pass in the resource and the value of the request that's how you tell the front end that this is something that needs to be downloaded so i'm gonna define some http headers and i'm gonna call them http headers and then do new http headers and then i wanna do http headers and add some headers so i'm going to add and the first thing i want to add is the file name so i'm going to do file name because we need to pass in the file name and the headers so that we can get that file name when the user is trying to save it we're going to get it from the headers and in here i can just pass in the file name that they gave me so the file name that we receive up here we pass it in here as a header and this response that we're sending back to the user and then we need to pass in the content deposition header which is super important so i'm gonna do the same thing again so http header is that ad and this time it's gonna be content deposition as you can see here it's coming from http headers and i'm gonna go ahead and just import this aesthetically so that i can have more space and what you want to do here is do attachment lowercase and then passing in the file name which is going to be something like this i'm going to copy this and then paste it here and i don't want this so we're gonna do file name and then set it equal to the file name that we got and i don't need this and what i need here is a plus sign okay so we're passing in the file name after the attachment as the content deposition header we're passing in the word attachment and then the file name is equal to the file name here or we can get the finding from the resource because the resource will also contain the file name so you can do something like this we sort that get file name as well that's just the same thing and after that we need to send the response to the user so i'm going to do return of course that's gonna be a response entity oops now resource response entity and i'm gonna send an okay to the user another thing that's really important is the content type so here i'm gonna pass in the content type because you need we need to have the content type of the file so that we can decode the file and the with the right content type and then download that file we're going to need this information on the front end and you're going to see how this is all going to come into play but we need to pass in the content type here of the file that we're sending to be downloaded so what i want to do is do parse media type and then call the files that probe media type and then passing in the paths the file path okay so this is gonna try it's not always gonna happen but it's gonna do its best to determine the media type of the file that we're trying to uh send back to the front end and then after that i wanna pass in the header so i'm gonna do dash headers and pass in the headers that we have http headers and then in the body of the response i wanna pass in the resource so here i'm gonna do resource okay so this is how you send something to the front end to be downloaded or make it downloadable you have to pass in this very important header and the response which is the content deposition and we can go into this if you want to take a look and you can see it here it's just a simple string that says content deposition that's just the key of the header so that's what we need to do here and we're going to go ahead and use postman so that we can test this application and make sure it's working fine before we actually go in the front end and then try to see if we can um you know use angular to make requests and then save files here all right so let's go ahead and test the application i'm gonna go ahead and start the application and let it come up all right so you can see it's running on port 8080 and i just realized that i have a typo here i'm going to delete that so that's supposed to be download so i'm going to restart stop and rerun all right so the application is running on port 8080 and let's go ahead and give it a try i'm gonna open postman so i'm pretty sure you guys already know what postman is but you can just use it as a api client to make hdb requests i'm gonna open a new tab here and i'm gonna go to localhost okay something is coming up and i want to go to file and then upload so let's see if we can upload something so i'm gonna go to http colon double for slash localhost 8080 because that's where our applicant is running on and then go to file slash upload so remember when we build the application the base path here is file so we have to go to file and then upload here and that's what i'm putting in here into this request okay so file upload so now we have to pass in the file in the body of the request so i'm going to go to body and this is going to be your form data and the key here is going to be file so remember this files key is important and if we go back we're passing in this key here okay so it's going to look for this key to pass in those files as multipart files okay so this name we pass in here and this they have to be the same okay and then we need to change this from text to file because we're trying to pass in files okay so we're gonna give the key for files and then select files so i'm gonna go ahead and select files and let's say i'm gonna select this powerpoint and open all right so the file is selected and now we need to send the request so i'm gonna make sure this is a post request remember the backend accepts a post request you can see here post mapping because we're trying to create some uh resource on the server and then send this request and see what happens okay we get in there 500 internal server error so let's go ahead and check out the back end and see what's going on i'm gonna bring this up a little bit and i can see i have this file size limit exceeded because the file was kind of too big as you can see here and that happens so let's see if we can find a smaller file so i'm gonna remove this and pick my profile picture here select it and then send okay so here's the file name so we know that it's working so to fix this problem with the size we can put a configuration in the application.properties so i'm going to show you how you can do this so i'm going to bring this down so we can ignore this for now i'm going to restart the application after i put in the configuration for the in the properties file so that we can allow big file size in this application so let's go ahead into the resources folder expand that and then go into the applicant.properties and what we want is spring that servlet and we want this file size and i'm gonna put a very large number here so that we don't have to worry about this again megabyte and the other one that we need is spring dot servlet and we want the max request size and i'm gonna put the same number here just like that okay so that way it's gonna allow you know very large files because i want to show you how i you know upload videos uh because it's gonna show the progress better so if you're just uploading like you know very simple pictures that are not very large then you're not going to see the progress bar so that's why i put a very large number here so that i can use videos and upload them so i'm going to go ahead and close that out collapse this and then restart the application all right the application restarted so let's go back and remove this and go ahead and select the video again open so the video is there and then send and you can see now it's everything is good so let's see if we can select multiple files as well so i'm going to select this and this and this so this request is going to probably going to take some time because those those video files they're very large so i'm going to go ahead and send this all right let's wait and see what happens this is on my local so it shouldn't take too long okay so we can see now all the files have been uploaded so i'm going to go ahead and duplicate this so i'm going to click duplicate and now i want to go to download and then pass in the file name and i need to change this to a get request and let's see if we can download this file so i'm going to copy the file name go back here pass in the file name now we don't have to send any value of any or anything this is going to be a path variable that's what we're looking for as the file name and then we're just going to do the logic from there let's go ahead and send this taking some time because those files are large this file is a little bit too large for this thing um so let's see if i can get this other one here and pass it here and send okay there we go so you can see the the file is in the response so that other file was kind of too big maybe because this file those files are really really large but you can see here 13 megabyte so that's uh it's not super large this one because it's only a minute but the other one i think it's like 10 minutes so it might be a little bit too big for this thing but you can see we have the file here as as the body of the request so let's see if we send a picture if we can actually get that picture so i'm gonna select this but i've already uploaded this but it's fine we can upload it again all right and then i'm gonna copy this name go back here change this and then send it all right you can see the picture is here and this is me so we're able to you can click here to save this as a file you can see now we have response.jpg it didn't get this file name correctly because we're not really manipulating the headers but we can get the headers and then get the file name and the header and then pass it here instead this is just this postman application that's just doing this by default so if we go into the response headers you can see we have the file name here and you can see the proper file name is here so whenever we're working the front end and we want to download the file we will pass in the file name from the headers which is going to call file name here that we're passing in as a custom header as you can see here so it seems like everything is working we can upload files we can download files so next what we have to do is to work on the front end so let's go ahead and start working on the angular application so i'm going to be using the angular cli to create the application and hopefully you guys already know all these things like you know npm and installing the angular cli and using the angular cli to create and manage angular application but that's what i'm going to be doing here so that's why i have this page up here if you need a reminder you need to have the node package manager and then with the node packet manager you can install the angular clr and then you can use the angular cli to manage your project your angular projects so i'm gonna do ng new and i'm gonna call this upload and download so that's gonna be the name of the front-end angular application and i'm gonna say yes on that and it's asking me if i want routing and i don't want routing in this application so i'm going to say no uh yes i'm fine with css and it's going to go ahead and create the application for us with all the boilerplate code and all the files so i'm going to wait i let this finish and then come back so the application has been created i'm going to go ahead and put this somewhere in the middle and make it a little bit bigger [Music] clear the screen and zoom in a little bit so let's go ahead and go inside of that upload and download um the first thing i want to do is create a service because i need to use that service to make http requests uh so hopefully you understand the concept of services in angular so i'm going to do ng generate service so that i can generate a service i'm just going to call it file and click enter i'm going to say yes all right so now our service is created and i'm gonna do code dot so that i can open this folder with visual studio code all right so this is our angular application and let's go inside of the source app and our service is here so i'm going to delete this spec file because we're not going to be dealing with tests and this is the service where we're going to be creating function to make http request to the backend and then you know pass those files to be saved and downloaded so what i want to do into the app module is to import the http client module because we're going to be using it so i'm gonna do http client module and this is supposed to be karma and now i need to import this so i'm gonna go up here under the ng module i'm going to import and pass in the name of the module that i want to import and that's going to be the hiv client module and this is coming from here slash http alright so we need to tell angular that we we're going to be using http and the way we do this is by you know going into the main module of the application in this case the app module and then pass it in here as one of the modules that we'll be using in this application so i'm passing the http client module because we'll be using the http client so now i can go back to the service and i can import the http client so i can do private i'm going to call it http and that's going to be of type http client okay it's coming from the same package as you can see here so now i'm ready to write functions and then use this http client so that i can make http requests so i'm gonna go ahead and define the server location so i'm gonna do private and i'm gonna call this server so that's going to be the back end that we just built and then set this equal to the backend server so let's just copy everything from here and then go back and paste it here that's going to be the backend just the base url so localhost 8080 because that's where the application is running that's the port and then here we want to define a function to upload files so define function to upload files and then we need another function we're gonna call uh we're gonna say define function to download files so pretty much everything that we did in the back in so we need the function to upload the files and another function to download the file so here i'm going to call this function upload and it's going to take a form data so i'm going to form data and give it a type of form data and this function is going to return observable so i'm going to do observable and this observable is going to view of type http event and inside of this event it's going to be a string array okay so you remember whenever we create all the files whenever we save them we return an array or a list of string okay so that translates to the front end that lists the java list translate into an array like a javascript array and in the front end and then here we're going to do return and we want to call the http http and we want to call the post because we're trying to post some information and again we have to pass in the type so string array and we want to pass in the server so here i'm gonna do the server name so this that server and you remember we have to go to file and then slash upload okay so that's the location where we're gonna send the request and then we're gonna pass in the form data so i'm gonna do form data and then i need to pass in some options which is gonna be in the form of an object so what i want to do is say that we want the report progress which is a boolean to be true so we want the http client to report us all of the progress of the files being uploaded and we also want to observe all of the events okay so all the http events that occurs we want to observe all of those events so that we know you know when the file is being uploaded when the connection is established and you know all the events that's going to happen as tcp is chunking the file up and then sending the file over to the wire so that's what we're telling sap client to give us we say hey give us all the report for the progress of the request and then we're gonna observe all of the response which you have to pass whenever you define your observable to be of type http event and if we go inside of this http event you can see that it's just all of the events that can occur whenever you make an http response so the sent event which is when the request is sent and then you get some headers you get the http response which is the actual response that's going to be of a certain type so you can see that the type that they're passing in here is only going to be passed to the response here and also for the http user event which is like a user-defined event here but we're not dealing with this but this http event is just a a type that's just all of the different types that can happen whenever you sent the http request and you can see the response again here is being typed here which is what we're doing here we say hey give us all the events and whenever the response come back inside of the body of the response we're going to have a string array or a list of of string which is going to be all the file names that we uploaded and then we're going to do something similar to the for the download so i'm going to copy everything here go down here and paste this this time we're gonna take the file name so i'm gonna call this file name and of course this is gonna be of type string okay we just need the file name and the return type again because we need to observe all of the you know chunks being transmitted over to us so again we're gonna say hey we need an http event type here and this time it's not gonna be a string array and the body of the response but it's gonna be a blob okay which is some sort of a binary representation of a file here and this needs to go to download and since this is a get request so i'm going to remove this and we don't need to type this it already knows what it's doing and we're going to remove the body of the request because we don't need it and we also need to pass in the file name as the path variable so here i'm going to go ahead and do forward slash dial assign open and close curly braces and then pass the file name here and then the last thing we have to do is to do is to tell the http client that the response type this time is going to be of type blob so the http client will note that the response is going to contain blob information of some sort of a binary or some buffer of some array of some sort and then we just need to change this to download okay so we're going to upload files using this function up here and then we're going to download files using this function down here okay so that's what we're going to do so notice that i'm not passing in a type here again like i'm doing it for this function that's because you don't need to pass in the type here whenever you're returning blob and if we go into into the definition of this get here you can see that it already knows that it's going to return this blob and up here you see that this is not a generic so it doesn't take any type here you just say get and then pass in your url and all of your options but if we look at the other one which is up here for the post request you can see that we're going to return an http event of type t so that's going to be the type which we're specifying here string array but also we have to do that as well up here we have to pass in the same type here which is what we're doing in here so you can see that they're not the same so you might want to say hey we need to tell this get to return you know blob information but you don't need to pass this here as per the definition file as you can see here uh from angular or from google so that's all we have to do in our service and we're going to inject this service in our main component and then call those functions to upload and download files so let's go into the main application so the appcomponent.ts and i'm going to remove this uh title here so what i want to do first is inject the file service so here i'm going to define a constructor so i'm going to do constructor and inside of it i'm gonna do private and i'm gonna call the file service and i'm gonna give you the type of file service okay so we're gonna inject the file service inside of this component so that we can use the file service here so what we want to do now is to define a function to upload files right which is going to be so we're going to call it on upload files and this function is going to take an array of files i'm going to call them files and it's going to be of type files already and it's gonna return void and then here what we want to do is to create the form data and then put all of the files inside of that form data and then call the service and then send those files over to the service so if we go back to the service real quick you can see here the service is expecting a form data and this is how you get information from a form data in the back end you pass in the key for the input and then it will map whatever the value is for that input into the data that you want to get here in this case we're getting a list of multiple files because we know that's what it's going to be so if that was going to be like some string you would put a string here and then give it a variable name here as the parameter so let's go ahead and create this form data so i'm going to go ahead and do a constant form data and then call the constructor so noon form data and then once i have the form data i want to iterate over all of the files that i get in this function and then put them inside of deform data so the way to do this uh is to for and then here i'm gonna do for every file of the files that i get so for every file in this file we're gonna loop through all of them what we want to do is we want to go ahead and then add them to the form data so i'm going to form data and then i'm going to do append and then here i'm going to pass in the information that i need the first is the key so we have to do files now this name here which is the key and the form has to match what we defined here remember we defined this as files so it's similar to us making sure that when we use postman this key here and the form data you can see it's the same name same idea we make sure this name was or the key was files otherwise it will not be able to map those values and then get the information you will be looking for files and if it's not named files then it won't be you won't find it you will say hey i couldn't find this and then we'll get an error here and we don't want that to happen so we have to make sure the names are the same for the key here so let's go back real quick so this has to be file and then we're gonna pass in the actual file so we're gonna do file and then we can pass in the file name and then i'm gonna close this and i need to come back right here okay so we put all of the files that we get in this array whenever this method is called from the template and then we're going to loop through all of them and then put them in this form data here i just put this on one line so you can see here it's a you know regular normal loop so four whatever and then put everything in but i want to keep it on one line i think it's it looks nicer so then at this point we can go ahead and call the service and then uh upload the file so we're going to call upload files and then of course this is going to take the form data so we're going to pass in the form data and since this is unobservable so the request is going to take some time as you saw whenever we made requests using postman so we need to watch for the response so here i'm gonna subscribe to this uh hopefully you guys already know what's going on here when we use observable we have to subscribe to the observable and this is also a cold observable so it's not even gonna emit it's not even going to run or this function is not even going to run if we don't subscribe to it so here we know we're going to get some event right because that's what we're expecting so once we get those event we can actually run some logic so what i want to do here the first thing i want to do is console.log so that we can see what's going on so i'm going to say hey log those event and the second thing i want to do is to call another function that's going to report or do the logic to report the progress so here i'm going to do this report progress and i'm going to pass in the event so here i'm going to do event so this function doesn't exist yet so i'm going to go ahead and use the quick fix to go ahead and create some declare and close this okay so this function is declared here and i'm going to make sure it's uh private okay because it's only going to be used in here it's not going to be using the template so i'm gonna put this down for now and then we're gonna continue with this so all we have to do whenever we get the response from the server all the responses are gonna come okay so not just the actual response when everything is saved but we're gonna get all the events that are going to be occurring as the response is being made as the file is being saved and then eventually we'll get the response and then i want to handle some errors so here if i get some error and i want to do some logic here so here i'm going to do uh just console.log that so i'm going to console.log and then log the air so that we can see something and we need to put this inside open and closing curly braces because we use them up here i have to use them down here as well and the reason i'm using the curly braces because i need multiple lines so that i can console like this but otherwise i could have just gotten rid of those and then remove this line and remove everything just like that that works fine as well okay so that would work and then here i'll do the same remove the curly braces remove this move this up and then remove this all right so you can see it's nicer but with this syntax you can only have one line and i need to have multiple lines so that i can console log the information so i'm gonna go ahead and put this back just like that all right so this is it for the upload and you're going to see how we're going to use this function in the template in a minute so let's go ahead and do the same for the download again i'm gonna copy this and then go down and here define a function to download file so that's what we're doing here and i'm gonna call it on download files and here we need the file name so i'm going to pass in a file name and that's going to be a string and in this case we don't need any form data so i'm going to go ahead and remove that and we just need to call download file on the service and then pass in the file name okay and we're going to do the same thing we're going to get a bunch of events we're going to console log those and then pass those events to the report progress and then that's going to report the progress that you saw when we did the demo and then we're going to console.log any errors if we get any errors so the next thing we want to do is to work on this report progress so let's go ahead and jump right into it so the report progress is going to be fairly simple the first thing we have to do you can see on line 34 here we're getting an error that's because this function except the string array which we get when we uh call the upload as you can see if i hover over this event it's of type http event and then the body is going to be a string array so it's not complaining here but it's complaining well actually here under report progress but it's complaining for the download because this download is going to return blob as you can see here but then this only accepts string array so we can say hey this is going to accept string array or it can also be a blob so here we're going to say blob okay oops just like that so now you can see it's not complaining anymore because we make this a little bit more generic so what we have to do here is to just take this event that i'm gonna call http event okay we're gonna just determine which event we're on and then we can use the information we get from that event to determine you know the amount of data that is loaded and the amount of data that is the total and we can use that to determine the percentage and let's go ahead and work on that so the first thing is this is going to return void so make sure we put in the return type here and then what i want to do is to create a switch and then switch on the different event type so i'm going to do switch and what i want to switch on is the http event.type okay and if we go into this type you can see that this type can be zero which is when the request was sent out over to the wire like the network wire it can also be upload progress in this case that's the first and then the response headers that's two download progress and then the actual response so the full response including the baddie and then the user-defined one so we're going to be using all of those uh four or five so one two three four five because we don't have any user any custom event but we're gonna be using those on those four well mostly those four because we don't need to know well not that we don't need to know but we're not going to use this set event for anything but we need the upload progress we can take a look at the headers and the download progress and whenever we get the response okay so that's what this um http event type is and that's what we're switching on so we're switching on the type whenever it's you know sent or we get the upload progress or download progress so here i'm gonna use the switch and then what i want to do is to switch over the different cases so here i have a case in that case is http event type that let's say the upload progress okay so whenever the event type is upload progress we're gonna go ahead and do a certain logic if it's download then we're going to do a different logic if it's the response then you know we might just take the response body and send something to the user or something like that so if it's progress what i want to do is call let's say update status so i'm going to create another function down below and i'm going to pass in the http event tab loaded and the total so i'm going to copy this paste it here and here i want the loaded so loaded so the amount of data that's been loaded in the total so that we can use this information to determine some sort of a percentage and then here i know this is uploading okay so i'm telling the function that i'm gonna define that this is the uploading that's happening now and then after that of course we have to break okay so we're gonna break and let's go ahead and define this uh we're gonna work on it in a minute so that's for the case for the upload progress so if it's download progress we're going to do something else i'm going to copy this go on a new line and do another case for download progress okay so if it's download again we're gonna do the same thing send the information over to the to this function and this function is gonna report the progress to the user interface and i need another case for the headers so i'm gonna go down and do another case so i'm gonna change this to the headers so if we get all the headers uh in this case i'm just gonna console log them so i'm gonna do console.log and we can do something like header returned and then we can look at the event okay so this is gonna just console log the response headers and then the most important in case we get the response i'm gonna paste this again so in case we get the response that's when we need to either download the file or send the response over in case they're uploading the file and then show all of the file names so if it's the response what i want to do is i want to check to see if i have an array of file in the response body so what i can do is do the http event and then access the body and then see if it's an instance of the array okay so if it's an array then i know this is the response with the upload and then i can run a certain logic here and then otherwise i know this is the download so i'm gonna run the download logic here and we're getting an error here because this is supposed to be the response okay so that's the only time this event is going to have a body whenever it's response so that's why it was giving me this error so if it's an array the body so we know that this is the response whenever they upload files so what i want to do is to loop over all of these files and then add them to an array so all the file names we're going to get and the baddie we need to show them on the screen so that the user can see them so i can do four define a constant file name of the http event that body because we know it's going to be an array we want to let's say this file names that's going to be a property on the class and let's do on shift and then pass in the file name okay so we're going to define this property right now and quick fix declare let's scroll up so the file name is going to be of type string array and we're going to initialize it as an interior okay so this is the file names that's going to hold all of the file names of the file that we're going to get from the backend and then once we get the response we just you know add all of those files inside of this file name here and we use unshift instead of push so that we can add to the beginning so that the most recent can be on top and the other case that we have so whenever the response comes back and it's not like the body is not an array then we know it's the blob that we get okay so we can go ahead and run logic here so that we can save the file and i'm gonna go ahead and use a library so that this can be easier for us so let's go back to the browser and the library that i'm going to be using it's called file saver and you can just search it on npm it's quite popular so it's got almost 1 million download per week so i'm going to go ahead and just click this so that i can copy this command and then go back to the application and open the terminal and i'm just gonna paste this okay npm install and then file saver and then run this we're gonna make sure this is downloaded all right so let's scroll up a little bit so zero vulnerabilities you can see it's been added in our package so just to double check i'm gonna close this go to the package.json and you can see if we go over to the dependencies it's right here okay file saver now we can use this file saver to save file on the client browser so let's go back to the application and let's go ahead and import that so i'm going to go up here and i'm gonna do import so the import is gonna be a little bit different so you have to give it a name yourself so i'm gonna do save as and this is supposed to come from file saver okay so you see it came up here because we installed the dependency and we're getting an error here because we haven't used it as you can see save as declare but its value is never is never used or read so we're gonna use this save as to save this file on the client so let's go down here and we know this is going to happen in this logic whenever uh the value of the request is not an array then we know it's the blob or the binary that we're getting in the baddie so what we want to do is call the save as i'm going to save as and then here we can create a new file so i'm going to do new file and what we have to pass in here is an array with the binary data so here i'm going to call in the http event that body because i know that's gonna be some binary data that i'm gonna get and then we have to pass in the file name now remember we're passing in the file name as a header because we can just say you know like file name here or something like that like uh uh file right because this is always going to be the file name for all the files so we need to have a way to retrieve the file name dynamically from the backend which is what we did when it when we pass in the file name as a header so i can grab that header from the request so i can do http event that headers so that i can access all the headers and i can call the get and then pass in the name of the headers that i'm looking for or the key in that case that was a file name so that file dash name okay make sure this is spelled correctly so we pass in the file name here so the file name for the save as whenever it's gonna save the file on the client computer it's gonna be the actual file name that we're getting from the back when we're accessing that using the headers and that's what we set in the download here so if we scroll down you can see in the download we set those headers and the key is file name and then we're passing in the actual file name so we should be able to retrieve this file name whenever we are in the front end as a header here which is what we're doing by calling the http event headers get and then the file name and then the last piece of information we need to pass into this save as is the type of data so if it's application.json or if it's of some png or some video so we have to pass in the type so i'm going to go on a new line and do type and then i'm going to pass in the content type so here what i want to do is do dal assign open and close curly braces and i'm going to access the http event dot headers again and i want to get the content type so i'm going to get and then pass in the name of the headers that i'm looking for in that case that's the content type so content dash type so that's going to give me the content type and the headers and then i need to tell it how to decode this so i'm going to put a semicolon and then i'm going to do character set and then set this equal to utf-8 so that way this save as will know how to save this information with the right format and the right character set i need the closing curly braces here and semicolon and one in the beginning and i need a comma right there oops okay so that's all we have to do here so you can see that we're getting an error here and if i put my mouse over here it says that the body can be null okay so and we can't assign null to um to this new file here which takes uh that part and this is just typescript configuration yelling at us this code is literally fine so one way we can fix this is to go into the um let's see the ts configuration so this file right here and then comment out this strict true here or turn it to false okay so if i for instance uh comment that out and go back you'll see that um this is fine right because it's checking and you say hey there's a possibility that this body might be null and that will that might cause your code to break so it's doing this streak checking for us so you can disable this if you don't want to but that's going to come down to how you want your developers to work because sometimes this is something that is set by like your team lead or something because they want to enforce the good practice so what i'm going to do is i'm going to put it back so i'm going to leave it here and i'm going to go ahead again you can see it's going to load and give me this area and one way to fix this is to just put an exclamation point here and that means that you're certain that this is never going to be null and it's just going to leave you alone and you can do this for this for here too because it's going to give you the same the same message that this can also be null and it's true there's a possibility that this address doesn't exist and it's going to give you null but in our case we know it's going to be there so we can just put this exclamation point here and that will do the trick and another way we can save the file is by creating a new blob instead of a file so i'm going to go ahead and show you an example so i'm going to copy this and then go down and paste it okay so instead of a file you can say blob and this take the oops and this is going to take the the binary so whatever we're getting in the body and then an object so here i'm going to put open curly braces and that's going to give me the name of the file and i'm gonna remove that one and i'm gonna pass in the type so i'm gonna remove this move the type up here and this is an object so i'm gonna put open curly braces and scroll over and then after that i'm going to pass in this and i need to close this with some comma i'm going to put this on a new line so you guys can see better and then remove this guy right here and remove this okay so that's another way you can do this so you can create a blob this time you pass in the an object as you can see here for the type and then you pass in the name of the file so either with a blob or with a file either one will work so we don't need both of them so i'm gonna maybe comment this one out so you can use it whatever your preference is it's gonna do the same thing so now what we have to do is to work on this function to report the progress so we have the loaded that's gonna be a number the total that's gonna be a number we don't need this undefined and then the request type so i'm going to call this request type which is a string so that can be either upload or download because we need this information to display the you know in the progress bar if it's a download or if it's upload and before i move on to this to work on this method let's just put a default here just in case uh just for sanity check and we're just gonna go ahead and do console.log whatever the case might be so let's do http event okay so that should do the trick so that we have a default uh at least for a sanity check even though we know uh well some one of those will hit except the um except the send event but we'll still be able to see it in the console log here when it's not any of those so now let's go ahead and work on this so what i want to do here is i want to create some property that i can use in the template so i'm going to do this file let's call it file status and let's give it a status and i'm going to set this equal to progress so let's do progress so that means that there is a progress going on so we can use that and let's see if we can define this on with the quick fix define the property and the next thing i want to do is to call the file status and let's also give you the request type so i'm gonna just copy this paste it here and then passing in the request type so that's gonna be either upload or download and let's also give it a percent so file status percent and we're gonna set this equal to the amount that is um loaded divided by the amount that is the total of the file so whatever load that we're trying to send over to the server we're going to take the total divided by the what is loaded and that's going to give us our percentage so i can just do take the loaded and then just divide that by the total and since this is gonna be a very small number we can just multiply it by a hundred all right so we're gonna multiply that by a hundred and just so we don't get like weird decimal number we're gonna call the math that around and just round it up so that's all this function is going to be doing and we can use this file status in the template so that we can determine if we're supposed to show progress and we can use the percent so that we can determine the percentage of you know the progress and then we can use the response type to determine if it's uploaded download because that's what we're passing in here you can see upload download and then again this is going to give us the same it can be undefined and then we just have to do this for this okay we're sure that it's it's always going to be there because if it's a blue progress then we're definitely going to have something but just in case which is why it's complaining because it's still possible that you might have this as undefined you don't know what can happen and this supposed to be downloading so downloading all right download so we know when it's downloading when it's uploading so at this point we're ready to start working on the actual template so we're gonna go ahead and do that make sure i put a break here but let's check to make sure this was created properly so it's it gives it a type of any that's not what i want so let's go ahead and uh set fix this real quick so let's say this is going to be an object literal and we're going to give it a status and we're gonna start with empty string okay so that's the status that we have and then uh request type so request type and this is also gonna be a string and that we're gonna start with empty string and then the last thing we have was a percent and we're gonna start with zero okay so that way this is typed properly um so if we go down here and we try to see what we can access on this object you can see we have the status and everything so since we're using typescript make sure everything is strongly typed but we could have left like the you know any up here and not define an object lateral but you know this is typescript so we want to make sure we type everything as much as possible so that's this is our fastest so at this point we're ready to create a form and then call the upload function and then see what we get on the screen so we're gonna go ahead and do this next so we're gonna go ahead and work on the template so that we can give the user the option to upload files and before i do that i'm gonna do a little bit of cleanup here i'm gonna make sure i declare this function as private because it's only going to be used in this in this class here we're not going to be using it in the template so i declare it as private so that it can only be accessed in this class so i think everything else looks good and another thing i did is since i'm gonna be using bootstrap so i went into the star.css i just import some bootstrap styles here hopefully you guys are familiar with that and what i want to do now is to run the application because i created this application i added all this code like the service and everything in the component and i haven't really like run this application so i don't even know if it's working so let's open the terminal and do serve oh not server yes you wanna do ng serve so let's go ahead and give this a try and see if it works so i ran the application and it looks like everything is fine but it's giving me an error for file saver because i don't have the type definition and we need to run npm install at types forward slash file saver and i look this up and it says that this package contain tab definitions for file saver so since this is just um the definition for the type then i guess i can just go ahead and install it that's not gonna hurt anything so i'm gonna go up here and clear this terminal and then install this and you can see i get the error here as well so let's so let's make sure we install this so that we can get rid of this error okay it's over so i'm going to close this and you can see now this air goes away and i'm gonna go back here and restart the application make sure everything looks clean all right the application is coming up and we got an error here because we deleted the title so let's go ahead and clean this um html let's go here i'm gonna go ahead and clean everything and just say um let's put a h4 and then just say uh yellow or something so that should fix it and i'm gonna restart this and make sure it looks fine i like when i have a clean first run so we're gonna go ahead and let this come up all right um this is because we're using an external library so that's why it's giving us this little message here but that's not a problem and i'm going to show you how we can fix this in a minute so let's see if we can access the app and you can see hello here check the console everything looks clean okay so this is the same warning again and i'm gonna show you how we're gonna fix this warning because we're using this file saver and it considered like a common gs library or dependency or something like that that can affect our performance but if we trust this file saver then we can just put a little bit of configuration and that's gonna get rid of this uh warning so it looks like the application is running uh fine so i'm gonna go ahead and put in the html for this so let's go back to the application and let's just remove this hello and i'm just going to go ahead and paste the html content and i'm going to show you what that looks like on the ui okay so we have zero functionality here everything is showing at the same time but we have everything that we need so we have the you know the process file list that's going to be down there the form to select a file and then some text here so that we can tell the user what's going on here and you can see the progress here everything is there so what we have to do now is to use the information that we have so that we can manipulate this uh the content of this page because we don't want to show everything all at once like this so let's go ahead and open the application and in the html i'm going to go ahead and scroll up and the first thing i want to do as you can see here in this progress here i don't want to show this progress unless the status of the file being uploaded or downloaded is progress okay so you remember we defined this uh down here this file that is here that's going to be progress so unless this file status is progress we're not going to show this um this progress bar as you can see here so here i'm gonna do ng if okay and then here i'm gonna say unless this is progress and we need three equal sign and just like that okay so we're checking to see if the status and we don't need this dot uh if the status is progress that's the only time uh we're going to show this progress bar so now if we go back you can see it's gone it's not there anymore so that's one thing now the second thing we want to do is uh you can see here if we give this uh let's say a style so let's do style and then width let's say 50 okay and if we go back well i have to make sure we can see this so i'm going to remove this for now and go back make sure this is percent you can see that this is 50 filled now at this point okay so we can use the with css style to manipulate the progress of this so let's go back to the application and i'm going to put this back because we don't want to show this so we know we can manipulate the width on this d so that we can determine the progress so we can use the property binding that we have in angular and then use the percent on this to set this number as a percentage so what we can do here is we can do uh bracket because we're going to do property binding and then we can access the style and what we want is the width okay so the width and then we want to set the percentage and we're going to do percentage and then we can just set this equal to the file statistic percentage so here i'm going to say fast that is and then that percent that's what i would call it that percentage okay so this is going to set the width as a percent and it's going to use this number here so whatever the percent is it's going to style this appropriately so if i remove this again just so we can see this progress bar and go back you can see it's there but it's there's nothing there but let's test this out so you can see that it's really working so if we go here and we set this to let's say 50 okay and this is going to be temporary so if we set this percent to 50 um well this is not going to be called yet let's put this back and let's give it a default of 50 here so it's going to start at 50. so if we go back you can see it's 50. okay so that's how we're gonna manipulate this so let's put this back to zero and put the if statement back okay because we don't want to show this unless the um you know the this is progress this is in progress and then inside of here we can put you know uh upload you know or download right so if we go back then and well we have to see this again so let's make this i'm gonna leave this as 50 for now and let's just duplicate this line and comment it out and let's just remove this if so that we can see what's going on all right so let's go back you can see upload and download and this is the uh this is the start the this that we put in here okay so we can use property binding to show what's being done and then the percent that's being added so we can do double curly braces and then access the file status and then get the um you know request type so here we're gonna do that oops request oops request type okay so that's gonna tell us if it's upload or download remember we have this logic down here it's gonna either be you know upload or download and we just access this request type that we're setting either here when it's upload progress and in download progress we press and downloading so we can do this here and then for the percent we can put a space well make sure this is correct and then we can do the same for the percent and then here we're gonna do percent okay so that's gonna say you know downloading we can even put like dot dot if we want that doesn't change anything or we can just put it here like data dot and then dot dot okay so that the user knows that this is uploading i put a space here and put the percentage all right so that's going to be that you can see now it says 50 but since um we have empty string here to begin with so for instance if i say uploading dot dot and go back you see uploading 50. okay but we're gonna manipulate this dynamically let's go ahead and remove all this so remove empty string this is zero because we don't have any percent we started at zero and let's uh delete this line and then put this line back okay so now we know that this is going to work the way that we want it to work so now let's go ahead and scroll down and work on the form so here's the form you can see the form is here now we're not using the forms module because we're not going to do template driven or reactive form in angular we're just going to react to the input change event which is going to happen on this input here so that's why i didn't import the forms module or anything like that so another thing i want to point out to you is well first of all this type is file which is why we see it that way so that we can select the file and then we give it a name a file well we're already setting the name files here so even if this wasn't file i think it would still be fine we give it an id that we don't need so i'm going to go ahead and remove that but another thing is this other property called multiple okay we need this on the input so that we can um you know select multiple file when we open our file explorer on the computer from the browser okay so if you don't have this multi then um it's only going to allow you to select one file so we need to have this multi here and then this is just some css class coming from bootstrap so what i want to do here is to react on the change event so here i'm going to tell angular to react on that change event and then call call our function so here i'm going to pass in the name of our function in this case upload files okay so i'm gonna go back here past upload files and then to get the files from the um change event we can call the data sign event so that's gonna be the event and then we wanna go to target and then files okay so that's going to give us an array of files and if you guys want to see like what this looks like i can remove this part real quick and i can go ahead here um just console log everything from here and then comment all this out and let's just console log whatever we're gonna get here which is gonna be the event okay so i'm gonna remove this i don't want to need to give it a type and it's called file but that's going to be the events okay the change event that's going to be passed in here so this is again the cs configuration yelling at us but that should be fine so if we go back open the developer tool go to console clear it go in here um select the file you can see we have the change event okay so you can see type change because it's a change event and if you drill down you go in here you go to target and you should see files in here and you can see we have the file that we just selected okay so the name of the file and the type and the size etc so this is how we get the file from the input so now i can go back and undo all of this since you guys now see how we're gonna get the file from the event and then i can put this back so we're gonna go into the event target files okay and that's going to give us all of the files so whenever this change event occurs it will call that function pass in the files which is what this function is expecting which is an array of file and then we're gonna do our logic here so at this point the upload should work we can go ahead and test it just to make sure everything is working so let's go back to the application and let's see if something is going to work so i'm going to refresh it and then select the file okay you can see that it actually works which we get the type 0 which is when the set event occurs and we get this course error because we are on a different domain okay so the backend is running on 8080 and the front end is running on 4200 so that's gonna give you the course error because they're not on the same domain okay so we just need to put a configuration in the back end to allow the localhost 4200 to be able to access this um back-end application i'm pretty sure you guys are familiar with this um but i'm going to show you how i resolve it i have the code somewhere and then every time i'm building some application i just literally just copy and paste it and then make some changes here and there so let's go ahead and open the backend application and let's see if we go to the main application file so in here i just have to define a bin so i'm going to go down and paste the code and make sure everything is imported so this is a course filter bin and we're just defining what we're allowing the method that we're exposing the everything else so you can see here we create this url based configuration then we say hey we're going to allow credential we're going to allow origin which is going to be the 4200 and then we're going to allow those headers so the jwt which i'm not using here but there's one important one that i have to point out to you is this exposed headers remember we have a custom header and it's called file name as you can see here so we have to make sure this is exposed otherwise we won't see it on the front end okay so make sure you have this the way that i have it and then make sure you tweak it in and the way that you want so for instance we're not using any put or any patch or any delayed so we would have to delete those those three methods but i'm just going to leave them here they're not going to do anything this is just a demo but this is the configuration that i have i just have that piece of code somewhere and then whenever i need it i just copy and paste it because you know i don't want to keep repeating typing all of this but make sure in the exposed headers we expose our um you know file name which is a custom header because otherwise when we try to access it like when we try to do this um here it will be no okay it won't find this file name because it's a custom header and we didn't tell the back end to expose this header so i'm gonna go ahead and restart the application and let's go ahead and try it one more time so let's make sure this is coming up all right so it's a very small application you know took a couple seconds to come up and let's go back and refresh this and upload the file again all right so everything works but we get this any here and we get our 200 response here so we can see the loaded everything is here so it looks like it works but we have an issue with the downloading dot dot so let's go ahead and check this out to see what's going on here so here files okay report progress percent so everything looks fine i think after the after this is done then this becomes some undefined value because we don't have any loaded or total and it's still um looking at this so what i need to do is to stop this from showing so i can go up here and then i can say once we get the response and then we do all that we can just set this to done okay so that this doesn't show anymore so that means that once the response comes back and then it's gonna set this to done so that we don't have to see the progress anymore because it's going to give us some some weird number because this is going to be like undefined or something and it's going to try to you know calculate and compute this and it's not going to work so let's save this and i think that should be all let's go back and pick a file select it okay that was too fast pick a larger file you can see uploading and we see we still saw the n a again because after the even type one where we have the uploading then it's a different event that doesn't have the loaded or total so it's best if we move this to here as well okay so once we get the response we set this to done otherwise it's gonna do this and then it's gonna still do done so let's go back and try it again and upload a large file you can see the upload 100 and it's gone all right so now we can go ahead and work on the download so we don't even want to show this unless there is like file that have been processed so we're gonna put an if statement on that so let's go back to the application and go back to the template and let's scroll down a little bit so here is the where we're gonna display the list of all the files that have been uploaded so the first thing i want to do is to put a condition on this so ng if and we're gonna say if the file name so file names and we're gonna check to see if there is anything on the on the array so we're going to do left and check to see if this is bigger than zero okay so if this is the case then we're gonna show this um this list here and then here we can loop over everything so we can do ng 4 and we're gonna say for not for let file name of all the file names that we're going to get so all of the ones from this array that we define in the component so now we can show the file names and then in here we can just display those names so we're gonna do oops file name okay so we're gonna pass in the file name here and in the same way we can put the click event on this link here so i'm gonna do the call the click event on this link here and then once they click on this i just want to call the download so here i'm gonna call the undownload files and then pass in the file name so here i'm gonna pass in the file name that i received for each iteration here so pass in the file name so this is going to call the on download files and this is supposed to be file because we're downloading a file at a time all right so on download file this is supposed to be files because we can upload more than one files all right so that should work so let's go back and you can see now this is clean so i'm gonna close this a little bit so now i can choose the file you can see boom and if i click on download there we go boom let's see if i can upload a larger file so i'm going to scroll down select this big file you can see it's uploading uploading all right it's done and you can see the files right here so if i click on this file downloading downloading and there it is so you can see this is working fine and another thing is to verify the files that we're adding are there so let's close this and run it again just so we can get rid of those errors then i open another session and what i want to do while the application is coming up is going to the download folder and then go to the upload folder supposed to be uploads and we have a bunch of files here that we don't need to keep so i'm going to remove everything and we get an error here so these areas that we're getting they're probably coming from the configuration in the cs file so let's go back to the application and let's go to the cs config and if we scroll down so this is what giving us this error so the strict checking so i would definitely just remove this and let's go back i probably need to restart the app and run it again and you can see now it works fine okay so um those uh typescript configuration let me put them back so you can see those configuration they're important i'm not gonna say just remove them but sometimes they're they're a little bit annoying because you know they're giving you a bunch of errors so i'm going to go ahead and comment them out so you guys can still have them but this is where the what was causing the problem saying hey this doesn't exist this can be null etc and we know our stuff is not going to be null so you can see now everything works perfectly so let's go ahead and you know try this again upload 100 you can see all the events here and then if we click download and then you can see we can download the file and i want to show you the folder so i'm going to open it and bring it over so you can see at this point we have this file in there which we just uploaded so let's go ahead and clean that up again run that comment again delete that file you can see now it's empty and let's go ahead and upload files i'm going to take some files here and upload and bring this up you can see all the files are appearing here so this is working fine and again we can download everything you can see it's here and i can save it you can see that the name is the same so we don't have anything that like download that we have with postman because we're using the headers to get the name and you can see the file is working here it's a very simple functionality but then at the same time you really have to know what you're doing so that you can design it the way that you want and again you know we didn't follow all the best practice for this so for instance in the back end i didn't create like a service i did all the processing and put all the logic in the controller so you usually wouldn't do that if you're you know building a large application because you want things to be decoupled and you want to separate functionalities as much as possible uh so you would probably create a service and then put the logic in the in the service you wouldn't do it that way i mean there's other things i'm sure you guys are picking up but we're not following like the best practice this is just a quick tutorial uh so that i can show you how this can be done and again um in the front end we probably would have a service for this as well because you can see this is a lot of code here so you can probably just create a service for this and then make it update this status here so you would probably have like just this status object and then call a function that's just gonna um you know do the work here you probably wouldn't do it here you would have a separate service and another thing is we're not doing proper um error handling so you can see here i'm just console.log and you can't really do that in production you can console log things when you're deploying your application so we'd probably have like a way to you know send those areas to the front end either with an alert or some sort of a message or something with that the user can see so that they knew something went wrong and lastly i want to show you how you can fix this error here that we're getting here because we're using the file saver so if you click on this link it will tell you what to do all you have to do is to go into the angular.json and then add this allow common js dependencies and then put the file saver here so i'm going to go ahead and copy this and go to the angularjson file and here and i'm gonna search for this option right here and i'm just gonna put it at the bottom so i'm gonna go down here [Music] paste it here i'm not using load dash but i'm using file saver i'm going to do file saver and then save that and close it probably need to restart the application again run it again make sure it comes up all right so the application is up and now if we go back refresh you can see this area is gone so that's all i had for you guys you can go ahead and you know grab the code and then use this however you want in your application and i'll see you guys in the next one you
Info
Channel: Get Arrays
Views: 10,013
Rating: 4.9597316 out of 5
Keywords: spring boot, angular, file upload, file download
Id: n26StCRoeHA
Channel Id: undefined
Length: 97min 52sec (5872 seconds)
Published: Sat Apr 10 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.