Skip to content

Commit 0aa699c

Browse files
committed
first commit
1 parent ae002e9 commit 0aa699c

10 files changed

+175
-536
lines changed

src/app/app.component.html

+5-533
Large diffs are not rendered by default.

src/app/app.component.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ import { Component } from '@angular/core';
66
styleUrls: ['./app.component.css']
77
})
88
export class AppComponent {
9-
title = 'AngularUploadMultipleFiles';
9+
title = 'Angular Upload Multiple Files';
1010
}

src/app/app.module.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@ import { BrowserModule } from '@angular/platform-browser';
22
import { NgModule } from '@angular/core';
33

44
import { AppComponent } from './app.component';
5+
import { HttpClientModule } from '@angular/common/http';
6+
import { UploadFilesComponent } from './components/upload-files/upload-files.component';
57

68
@NgModule({
79
declarations: [
8-
AppComponent
10+
AppComponent,
11+
UploadFilesComponent
912
],
1013
imports: [
11-
BrowserModule
14+
BrowserModule,
15+
HttpClientModule
1216
],
1317
providers: [],
1418
bootstrap: [AppComponent]

src/app/components/upload-files/upload-files.component.css

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<div *ngFor="let progressInfo of progressInfos" class="mb-2">
2+
<span>{{ progressInfo.fileName }}</span>
3+
<div class="progress">
4+
<div
5+
class="progress-bar progress-bar-info progress-bar-striped"
6+
role="progressbar"
7+
attr.aria-valuenow="{{ progressInfo.value }}"
8+
aria-valuemin="0"
9+
aria-valuemax="100"
10+
[ngStyle]="{ width: progressInfo.value + '%' }"
11+
>
12+
{{ progressInfo.value }}%
13+
</div>
14+
</div>
15+
</div>
16+
17+
<label class="btn btn-default">
18+
<input type="file" multiple (change)="selectFiles($event)" />
19+
</label>
20+
21+
<button
22+
class="btn btn-success"
23+
[disabled]="!selectedFiles"
24+
(click)="uploadFiles()"
25+
>
26+
Upload
27+
</button>
28+
29+
<div class="alert alert-light" role="alert">{{ message }}</div>
30+
31+
<div class="card">
32+
<div class="card-header">List of Files</div>
33+
<ul
34+
class="list-group list-group-flush"
35+
*ngFor="let file of fileInfos | async"
36+
>
37+
<li class="list-group-item">
38+
<a href="{{ file.url }}">{{ file.name }}</a>
39+
</li>
40+
</ul>
41+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2+
3+
import { UploadFilesComponent } from './upload-files.component';
4+
5+
describe('UploadFilesComponent', () => {
6+
let component: UploadFilesComponent;
7+
let fixture: ComponentFixture<UploadFilesComponent>;
8+
9+
beforeEach(async(() => {
10+
TestBed.configureTestingModule({
11+
declarations: [ UploadFilesComponent ]
12+
})
13+
.compileComponents();
14+
}));
15+
16+
beforeEach(() => {
17+
fixture = TestBed.createComponent(UploadFilesComponent);
18+
component = fixture.componentInstance;
19+
fixture.detectChanges();
20+
});
21+
22+
it('should create', () => {
23+
expect(component).toBeTruthy();
24+
});
25+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { Component, OnInit } from '@angular/core';
2+
import { UploadFileService } from 'src/app/services/upload-files.service';
3+
import { HttpEventType, HttpResponse } from '@angular/common/http';
4+
import { Observable } from 'rxjs';
5+
6+
@Component({
7+
selector: 'app-upload-files',
8+
templateUrl: './upload-files.component.html',
9+
styleUrls: ['./upload-files.component.css']
10+
})
11+
export class UploadFilesComponent implements OnInit {
12+
13+
selectedFiles: FileList;
14+
progressInfos = [];
15+
message = '';
16+
17+
fileInfos: Observable<any>;
18+
19+
constructor(private uploadService: UploadFileService) { }
20+
21+
ngOnInit() {
22+
this.fileInfos = this.uploadService.getFiles();
23+
}
24+
25+
selectFiles(event) {
26+
this.progressInfos = [];
27+
this.selectedFiles = event.target.files;
28+
}
29+
30+
upload(idx, file) {
31+
this.progressInfos[idx] = { value: 0, fileName: file.name };
32+
33+
this.uploadService.upload(file).subscribe(
34+
event => {
35+
if (event.type === HttpEventType.UploadProgress) {
36+
this.progressInfos[idx].value = Math.round(100 * event.loaded / event.total);
37+
} else if (event instanceof HttpResponse) {
38+
this.fileInfos = this.uploadService.getFiles();
39+
}
40+
},
41+
err => {
42+
this.progressInfos[idx].value = 0;
43+
this.message = 'Could not upload the file:' + file.name;
44+
});
45+
}
46+
47+
uploadFiles() {
48+
this.message = '';
49+
50+
for (let i = 0; i < this.selectedFiles.length; i++) {
51+
this.upload(i, this.selectedFiles[i]);
52+
}
53+
}
54+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { TestBed } from '@angular/core/testing';
2+
3+
import { UploadFilesService } from './upload-files.service';
4+
5+
describe('UploadFilesService', () => {
6+
beforeEach(() => TestBed.configureTestingModule({}));
7+
8+
it('should be created', () => {
9+
const service: UploadFilesService = TestBed.get(UploadFilesService);
10+
expect(service).toBeTruthy();
11+
});
12+
});
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { Injectable } from '@angular/core';
2+
import { HttpClient, HttpRequest, HttpHeaders, HttpEvent } from '@angular/common/http';
3+
import { Observable } from 'rxjs';
4+
5+
@Injectable({
6+
providedIn: 'root'
7+
})
8+
export class UploadFileService {
9+
10+
private baseUrl = 'http://localhost:8080';
11+
12+
constructor(private http: HttpClient) { }
13+
14+
upload(file: File): Observable<HttpEvent<any>> {
15+
const formData: FormData = new FormData();
16+
17+
formData.append('file', file);
18+
19+
const req = new HttpRequest('POST', `${this.baseUrl}/upload`, formData, {
20+
reportProgress: true,
21+
responseType: 'json'
22+
});
23+
24+
return this.http.request(req);
25+
}
26+
27+
getFiles(): Observable<any> {
28+
return this.http.get(`${this.baseUrl}/files`);
29+
}
30+
}

src/index.html

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
<base href="/">
77
<meta name="viewport" content="width=device-width, initial-scale=1">
88
<link rel="icon" type="image/x-icon" href="favicon.ico">
9+
<link type="text/css" rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" />
910
</head>
1011
<body>
1112
<app-root></app-root>

0 commit comments

Comments
 (0)