How to Use Angular File Uploader With Mongodb
Athwart xiii drag and drop file upload tutorial; In this article; we will learn to upload multiple prototype files in MongoDB database using Node and Express.
In this tutorial we volition create a basic Angular app in which we will utilise to create a custom directive to build Angular elevate and drib functionality.
Tutorial Objective
- Building Angular drag and drib file uploading Layout with HTML/CSS
- Creating a Node server to upload prototype files
- Creating Custom Drag and Drib directive
- Using Multer for Multiple file uploading
- Multiple files uploading with progress bar
Angular xiii Elevate and Drop File Uploading Example
- Install Angular App
- Build Node/Express Server
- Build File Upload Rest API with Multer & Express
- Configure Node/Express Server
- Create Angular Drag and Driblet File Uploading Directive
- Create Angular Service
- Create Drag and Drib File Upload Component
Install Athwart App
Permit'due south start by installing basic Angular app, run the following command:
ng new angular-dragdrop-fileupload So, navigate to the newly created Angular project:
cd angular-dragdrop-fileupload Next, create Angular component for elevate and driblet file upload.
ng m c drag-drop Side by side, run command to install Bootstrap.
npm install bootstrap Add the Bootstrap CSS in package.json file.
"styles" : [ "node_modules/bootstrap/dist/css/bootstrap.min.css" , "src/styles.scss" ] Build Node/Express Server
Build a node server with express js to store the uploaded files on the MongoDB database. We will apply Multer to store the image files along with other NPM packages.
Run the command from Angular project'south root to generate backend binder:
mkdir backend && cd backend Create separate package.json for node server.
npm init Run control to install required NPM packages.
npm install body-parser cors express mongoose multer --relieve Also, install nodemon NPM module, it starts the server whenever any change occurs in server code.
npm install nodemon --save-dev Ascertain Mongoose Schema
Create models binder inside the backend directory, and then create a file User.js and place the following code inside of it.
const mongoose = require ( 'mongoose' ) ; const Schema = mongoose.Schema; // Define Schema let userSchema = new Schema ( { _id: mongoose.Schema.Types.ObjectId, avatar: { blazon: Assortment } , } , { collection: 'users' } ) module.exports = mongoose. model ( 'User' , userSchema) Build File Upload Rest API with Multer & Express
Let's first create a folder and name it public inside the backend folder. Hither, in this binder where we will store all the uploaded files.
Run the command from the backend folder's root.
mkdir public Create a routes folder inside the backend folder. Create a file user.routes.js inside of it. Here we sick import express, multer and mongoose NPM modules. By using these services nosotros volition build REST API for storing multiple files in MongoDB database.
Add the given beneath code inside the user.routes.js.
permit express = require ( 'express' ) , multer = require ( 'multer' ) , mongoose = require ( 'mongoose' ) , router = limited. Router ( ) ; // Multer File upload settings const DIR = './public/' ; const storage = multer. diskStorage ( { destination : ( req, file, cb ) => { cb ( nada , DIR ) ; } , filename : ( req, file, cb ) => { const fileName = file.originalname. toLowerCase ( ) . split up ( ' ' ) . join ( '-' ) ; cb ( null , fileName) } } ) ; var upload = multer ( { storage: storage, // limits: { // fileSize: 1024 * 1024 * five // }, fileFilter : ( req, file, cb ) => { if (file.mimetype == "image/png" || file.mimetype == "epitome/jpg" || file.mimetype == "image/jpeg" ) { cb ( cypher , true ) ; } else { cb ( nothing , imitation ) ; return cb ( new Error ( 'Only .png, .jpg and .jpeg format allowed!' ) ) ; } } } ) ; // User model permit User = require ( '../models/User' ) ; router. mail service ( '/create-user' , upload. assortment ( 'avatar' , 6 ) , ( req, res, next ) => { const reqFiles = [ ] const url = req.protocol + '://' + req. go ( 'host' ) for ( var i = 0 ; i < req.files.length; i++ ) { reqFiles. push (url + '/public/' + req.files[i] .filename) } const user = new User ( { _id: new mongoose.Types.ObjectId ( ) , avatar: reqFiles } ) ; user. salvage ( ) . and so ( issue => { panel. log (result) ; res. condition ( 201 ) . json ( { message: "Washed upload!" , userCreated: { _id: result._id, avatar: result.avatar } } ) } ) . catch ( err => { console. log (err) , res. status ( 500 ) . json ( { fault: err } ) ; } ) } ) router. get ( "/" , ( req, res, next ) => { User. find ( ) . then ( information => { res. status ( 200 ) . json ( { message: "User list retrieved successfully!" , users: information } ) ; } ) ; } ) ; module.exports = router; We used Multer's upload.array() method to upload the multiple files on the server. This method takes 2 arguments, beginning nosotros laissez passer the file name which we will exist using to store the file values. Second parameter relates to the number of file we can upload at a time. And so nosotros defined the reqFiles assortment here we will store the uploaded file's path with full URL.
Configure Node/Express Server
Create server.js file inside the backend folder. Then, identify the following lawmaking within the server.js file.
const limited = require ( 'limited' ) const mongoose = crave ( 'mongoose' ) const cors = crave ( 'cors' ) const bodyParser = require ( 'body-parser' ) // Routes to Handle Request const userRoute = require ( './routes/user.routes' ) // MongoDB Setup mongoose . connect ( 'mongodb://127.0.0.1:27017/mydatabase' ) . then ( ( x ) => { panel. log ( ` Connected to Mongo! Database name: " ${x.connections[ 0 ] .proper noun} " ` ) } ) . catch ( ( err ) => { console. error ( 'Fault connecting to mongo' , err.reason) } ) // Setup Limited.js const app = express ( ) app. utilize (bodyParser. json ( ) ) app. utilise ( bodyParser. urlencoded ( { extended : false , } ) , ) app. use ( cors ( ) ) // Make Images "Uploads" Folder Publicly Available app. use ( '/public' , express. static ( 'public' ) ) // API Route app. use ( '/api' , userRoute) const port = process.env. PORT || 4000 const server = app. listen (port, ( ) => { panel. log ( 'Connected to port ' + port) } ) // Error app. use ( ( req, res, next ) => { // Error goes via `adjacent()` method setImmediate ( ( ) => { side by side ( new Fault ( 'Something went incorrect' ) ) } ) } ) app. use ( role ( err, req, res, next ) { console. error (err.bulletin) if ( !err.statusCode) err.statusCode = 500 res. status (err.statusCode) . send (err.bulletin) } ) Open the backend/parcel.json file and change primary from alphabetize.js to server.js.
{ ... ... "main" : "server.js" , ... ... } Start Node Server
Open terminal and run command to starting time the MongoDB server.
mongod Then, open another terminal and run following command.
nodemon server.js Next, y'all can checkout node server running on the following Url: http://localhost:4000/api
| API Method | URL |
|---|---|
| GET | http://localhost:4000/api |
| Postal service | /api/create-user |
You can test out Angular file uploading REST APIs Url in Postmen:
Create Athwart Elevate and Drop File Uploading Directive
In this footstep, nosotros volition create HostBinding and HostListeners to manage the drag and drop functionality for Angular file upload chore.
Run control to create directive in Angular projection.
ng chiliad d elevate-driblet-file-upload In the drag-drop-file-upload.directive.ts file, we will define 3 HostListners such every bit Dragover, Dragleave and Drop forth with HostBinding for background-color.
import { Directive, EventEmitter, Output, HostListener, HostBinding, } from '@angular/core' ; @Directive ( { selector : '[appDragDropFileUpload]' , } ) consign class DragDropFileUploadDirective { @Output ( ) fileDropped = new EventEmitter <whatever> ( ) ; @HostBinding ( 'fashion.background-colour' ) private background = '#ffffff' ; // Dragover Outcome @HostListener ( 'dragover' , [ '$event' ] ) dragOver ( outcome : whatsoever ) { event. preventDefault ( ) ; outcome. stopPropagation ( ) ; this .background = '#e2eefd' ; } // Dragleave Event @HostListener ( 'dragleave' , [ '$event' ] ) public dragLeave ( event : whatsoever ) { event. preventDefault ( ) ; result. stopPropagation ( ) ; this .background = '#ffffff' ; } // Drop Event @HostListener ( 'drib' , [ '$effect' ] ) public driblet ( event : whatsoever ) { issue. preventDefault ( ) ; event. stopPropagation ( ) ; this .background = '#ffffff' ; const files = result.dataTransfer.files; if (files.length > 0 ) { this .fileDropped. emit (files) ; } } } Create Angular Service
We demand to create Athwart service, hither in this file we will create a method in which we will brand HTTP POST request to store the uploaded files in the mongoDB database.
Use JavaScript's FormData() method to store the Reactive Forms value in the database via Reactive Form. To track the file upload progress ascertain the reportProgress and notice values in Http method.
First, create service file using given control in athwart project.
ng 1000 due south elevate-drib Next, open the src/app/drag-drop.service.ts file.
import { Injectable } from '@athwart/core' ; import { Observable, throwError } from 'rxjs' ; import { catchError } from 'rxjs/operators' ; import { HttpErrorResponse, HttpClient } from '@angular/common/http' ; @Injectable ( { providedIn : 'root' } ) consign class DragdropService { constructor(individual http: HttpClient) { } addFiles(images: File) { var arr = [] var formData = new FormData ( ) ; arr.push button (images) ; arr[0].forEach((item, i) => { formData.append ( 'avatar' , arr[0][i]) ; } ) render this.http.mail service('http://localhost:4000/api/create-user', formData, { reportProgress : true, observe : 'events' } ).pipe ( catchError (this.errorMgmt) ) } errorMgmt(error: HttpErrorResponse) { permit errorMessage = '' ; if (error.error instanceof ErrorEvent) { // Get client-side error errorMessage = error.mistake.message; } else { // Get server-side error errorMessage = `Fault Code: $ {mistake.condition} \nMessage: $ {error.message}`; } console.log (errorMessage) ; return throwError (errorMessage) ; } } Create Drag and Drib File Upload Component
Now, we volition create the layout for drag and driblet file upload component. In this tutorial nosotros will exist using Reactive Forms to store the files and Node server to shop the files into the mongoDB database.
Import ReactiveFormsModule and HttpClientModule in app.module.ts file to enable the service.
import { ReactiveFormsModule } from '@athwart/forms' ; import {HttpClientModule} from '@angular/common/http' ; @ NgModule ( { declarations: [ ... ] , imports: [ ReactiveFormsModule, HttpClientModule ] , bootstrap: [ ... ] } ) export form AppModule { } Next, add together the code inside the app/drag-drop.component.html file.
<div grade = "container fileUploadWrapper" > <form [formGroup] = "form" > <div form = "row" > <!-- Progress Bar --> <div course = "col-dr.-12" *ngIf = "progress" > <div grade = "progress grade-grouping" > <div course = "progress-bar progress-bar-striped bg-success" role = "progressbar" [style.width.%] = "progress" > </div > </div > </div > <div class = "col-medico-12" > <div course = "fileupload" appDragDropFileUpload (click) = "fileField.click()" (fileDropped) = "upload($consequence)" > <bridge grade = "ddinfo" > Choose a file or drag here </span > <input type = "file" name = "avatars" #fileField (modify) = "upload($whatsoever($upshot).target.files)" hidden multiple /> </div > </div > <div class = "col-medico-12" > <div class = "epitome-list" *ngFor = "allow file of fileArr; let i = index" > <div form = "contour" > <img [src] = "sanitize(file['url'])" alt = " " /> </div > <p > {{ file.item.name }} </p > </div > <p grade = "bulletin" > {{ msg }} </p > </div > </div > </grade > </div > Apply design to Angular drag and drib file uploading component, navigate to styles.css and paste the following code.
* { box-sizing : edge-box; } body { margin : 0; padding : 25px 0 0 0; background : #291464; } .container { margin-pinnacle : 30px; max-width : 500px; } .progress { margin-bottom : 30px; } .fileupload { background-prototype : url ("./assets/upload-icon.png") ; background-repeat : no-repeat; background-size : 100px; background-position : center; groundwork-color : #ffffff; height : 200px; width : 100%; cursor : pointer; /* edge: 2px dashed #0f68ff; */ border-radius : 6px; margin-lesser : 25px; groundwork-position : middle 28px; } .ddinfo { display : block; text-align : center; padding-summit : 130px; color : #a0a1a2; } .prototype-listing { display : flex; width : 100%; background : #C2DFFC; border : 1px solid; border-radius : 3px; padding : 10px 10px 10px 15px; margin-bottom : 10px; } .prototype-listing p { line-height : normal; padding : 0; margin : 0 0 0 14px; display : inline-block; position : relative; meridian : -2px; color : #150938; font-size : 14px; } .message { text-align : middle; color : #C2DFFC; } .remove { background : transparent; border : none; cursor : pointer; } .profile { width : 40px; height : 40px; overflow : hidden; border-radius : 4px; display : inline-block; } .profile img { width : 100%; } .remove img { width : 15px; position : relative; top : -2px; } .fileUploadWrapper .card-torso { max-meridian : 330px; overflow : hidden; overflow-y : machine; } @media ( max-width : 767px) { .container { width : 280px; margin : 20px car 100px; } } in order to remove strict type check alert in typescript prepare "strict": imitation under compilerOptions in tsconfig.json file.
Paste the following code in app/drag-drop.component.ts file:
import { Component, OnInit } from '@angular/cadre' ; import { FormBuilder, FormGroup, FormArray } from "@angular/forms" ; import { DragdropService } from "../dragdrop.service" ; import { HttpEvent, HttpEventType } from '@athwart/common/http' ; import { DomSanitizer } from '@angular/platform-browser' ; @Component ( { selector: 'app-drag-drop' , templateUrl: './drag-drop.component.html' , styleUrls: [ './elevate-drop.component.css' ] } ) consign grade DragDropComponent implements OnInit { fileArr = [ ] ; imgArr = [ ] ; fileObj = [ ] ; form: FormGroup; msg: string ; progress: number = 0 ; constructor ( public fb: FormBuilder, private sanitizer: DomSanitizer, public dragdropService: DragdropService ) { this .form = this .fb. group ( { avatar: [ null ] } ) } ngOnInit ( ) { } upload ( e ) { const fileListAsArray = Array . from (e) ; fileListAsArray. forEach ( ( item, i ) => { const file = (due east as HTMLInputElement) ; const url = URL . createObjectURL (file[i] ) ; this .imgArr. push button (url) ; this .fileArr. button ( { item, url: url } ) ; } ) this .fileArr. forEach ( ( detail ) => { this .fileObj. push (item.item) } ) // Set files form command this .form. patchValue ( { avatar: this .fileObj } ) this .class. get ( 'avatar' ) . updateValueAndValidity ( ) // Upload to server this .dragdropService. addFiles ( this .course.value.avatar) . subscribe ( ( outcome: HttpEvent< whatsoever > ) => { switch (event. blazon ) { instance HttpEventType.Sent: console . log ( 'Request has been made!' ) ; break ; case HttpEventType.ResponseHeader: console . log ( 'Response header has been received!' ) ; break ; case HttpEventType.UploadProgress: this .progress = Math. round (event.loaded / event.total * 100 ) ; console . log ( ` Uploaded! ${ this .progress} % ` ) ; break ; case HttpEventType.Response: console . log ( 'File uploaded successfully!' , issue.body) ; setTimeout ( ( ) => { this .progress = 0 ; this .fileArr = [ ] ; this .fileObj = [ ] ; this .msg = "File uploaded successfully!" } , 3000 ) ; } } ) } // Clean Url sanitize ( url: string ) { return this .sanitizer. bypassSecurityTrustUrl (url) ; } } Next, get to app.component.html file and remove the electric current code and add the given component tag into it.
<app-drag-drop > </app-drag-driblet > Run command to start your Athwart projection.
ng serve --open up Conclusion
Finally, Angular Elevate and Driblet multiple files uploading tutorial with MongoDB & Multer is completed. You can use the given link to download the sample project.
Git Repo
Recommended Posts:
garnergromemence01.blogspot.com
Source: https://www.positronx.io/angular-drag-and-drop-file-uploading-with-mongodb-multer/
0 Response to "How to Use Angular File Uploader With Mongodb"
Post a Comment