Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedIn
George Anderson
Frontend and backend development guru, lover of all things computer... and cats! Hopes to make your coder life a breeze by sharing some tips and tricks of the trade.
Posted on Apr 2nd 2019

Web development has become more dynamic with time, mostly due to the continued development of various languages, tools, and frameworks, one of them being Angular. The recent release of Angular 7 comes with new features, such as virtual scrolling, drag and drop, and some CLI updates, among others.

In this article, we will be building an application that shows how file upload works (specifically, image upload). It also uses the Angular Material and its CDK module to show the drag and drop feature introduced with Angular v7.

Below is a screenshot of what we will be building:

Getting Started: Configuring the Development Environment

  • For this tutorial, you can download and install Angular IDE.
  • However, if you already have an Eclipse installation you are happy with, add Angular IDE to it from the Eclipse marketplace.
  • If you already have CodeMix installed, simply ensure you have the Angular extension Pack installed from the Extension Manager at Help > CodeMix Extensions.

Optimize your Angular development with Angular IDE powered by CodeMix. If you’re new to Angular, use our new eLearning infrastructure to easily build an Angular front end, using Angular features along the way to make the job easier.

Creating an Angular Project using Angular IDE

We will create our application using the Angular IDE project wizard. We will be using Angular CLI version 7.3.6 and the latest version of all the tech libraries and stacks, as at the time of this writing. To create a new Angular project, navigate to File>New>Angular Project.

The next step is to add the Angular Material module that also adds the CDK module (which contains the drag and drop feature in Angular v7). Note that this also optionally adds the animation module. We will include the Angular Material module by running the command below in Terminal+:

At this stage, we will move on to pulling in some dependencies that we will use to build the application with the command below:

  • Express is a Node.js module that simplifies the creation of a node server.
  • Cors is a Node.js module that provides a middleware to handle cross-origin resource sharing.
  • Multer is a Node.js middleware for handling “multipart/form-data”, which is primarily used for uploading files.
  • Mkdirp is a Node.js module for directory creation.

Setting up the Backend Server

Now, we can begin the development of the application. First, we will create a server.js file in the root directory of our application. This file will contain the server setup, multer configuration and the only route of the application. The route will accept the files submitted, save them and return a path to the files. 

In the code snippet above, we set up Express to load files in the public directory in the root of the project as static or public files. This allows the files to be rendered through requests to the file path from the root URL. For example, for a file image.jpg in the public directory, a request to http://localhost:5000/image.jpg from the browser will render the image).

Next, we set up the configuration for the multer middleware, which determines how and where the files are to be saved. In this case, we store the files in the public/images/uploads directory. In this setup, we made use of the mkdirp module to create the uploads directory, if it doesn’t exist.

Afterwards, we created the route which the images will be posted to. On the route definition, the multer middleware (object) is passed as a parameter. This helps the route to accept single file upload, with the expected file in the field name image. We then return the file’s path as part of the response, or return an error if no file is found.

We can run the application back end using the command given below:

Setting up the Front End

Now that we have the application’s back end running, let’s begin the development of its front end. For brevity’s sake, we will be building the entire application in just one component (i.e. the app component).

First, we need to register the drag and drop module from the @angular/cdk module in the app.module.ts file, as shown below:

Next up, we set up the app.component.ts file. This is where most of our application logic resides. 

Here, we will set up the upload event handler, the image upload handler, as well as the drop event handler of the CDK drag and drop lists. 

At the top of this file, we imported the modules needed for this component, which include the HttpClient and the HttpEventType. In Angular, the former is used to handle the request, much like the request handling using Axios. HttpEventType is used to check the response event type (uploadProgess event is when the request data is still being uploaded, while the response event is when the response data is sent to the client). We also imported three things from the CDK module. The first one is the moveItemArray method which is used to move items from one position to another (i.e. it rearranges the list). The second one is the transferArrayItem method which is used to transfer an item from one list to another. Finally, we imported the CdkDragDrop which is used to hint the type of event the drop event handler expects.

Next, we declared a model to describe the file struct which includes the file upload progress as a percentage (usually this class would be in a separate file and folder as a model).

Next, we defined three methods that handle specific events in the component, and they are as follows:

  • The selectFiles method is used to handle the change event of the input field. It accepts the event that has a FileList.
    Note: Although FileList has a length property, it is not an array; hence, it does not have high order methods, such as map, filter, etc.
    The selectFiles method filters the list and returns only valid images for upload.
  • The uploadImages method sends the images to the server one after the other, using the FormData object provided by JavaScript. In the subscribe method (more like the then method of JavaScript promises) we accept the response event and act accordingly. For example, if the event is an upload progress event, we get the percentage of completion and return it to be rendered to the user. When the request has been completed, we push the returned image URL to the array of uploaded image URLs.
  • The drop method is used to respond to the drag and drop event. This method handles an item moving up and down a particular list, or between two connected lists. In this method, we can attach server calls (to save the changes) when we move an item from the regular list to the favorites list (although in this application, changes are not persisted).

Next, we edit the app.component.html file. Here, we render the list of images and the input for the image upload. The file is edited as shown below:

Here the file input is hidden from the user and given an #imageInput handle which is used by the button shown to the user to trigger the click event of the file input. Also, the selectFiles method previously defined is attached to the on change event of the file input.

Next, the upload progress of the files is displayed. This is achieved using the upload progress attached to each ImageFile object in the images array.

Finally, we render the uploaded images using their URLs in the imageUrls and favorites array. For the first array, we attach the cdkDropList attribute to indicate that this is a list with the drag and drop functionalities handled by the CDK module.  We then pass the array of image URLs to the cdkDropListData property for the CDK module to handle the changes using this array as its data target. We then connect it to the other list (in this case, the favorites list) using the cdkDropListConnectedTo property. Next, we attach the drop event handler using the cdkDropListDropped Angular created custom event. Finally, on each item, we attach the cdkDrag to make them draggable and droppable. We do the same for the favorites list and name it the #secondList. Now we should be able to drag items between lists, as well as up and down the same list.

Run the Application

Run the application from the server tab of Angular IDE.

Now we are done with the development of this application – congratulations!

Conclusion

In this article, we created a Node.js back end using Express, which accepts file input, saves it, and returns the file path for rendering. We built a front end with the Angular framework, taking advantage of the Angular CDK’s drag and drop module.

As always, this is a simple application that can be improved by using data persistence, and breaking up the application into smaller, more manageable components. Moving the application’s data handling into a service would be a good step too.

The code for this application can be found in our GitHub repository.