While uploading a large file to server there is a very high chance of internet disconnection so giving a resumable option in upload will be very useful in uploading a large file to the server.
I have used the fs module of the node.js to upload file in the server.
import { Component, OnInit } from "@angular/core";
import { HttpClient, HttpHeaders, HttpRequest, HttpEventType } from "@angular/common/http";
declare const socket: any;
// const socket = io("http://localhost:3000");
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent implements OnInit {
title = "resumeUpload-ui";
selectedFile;
fReader;
name = "";
uploadPercent;
color = "primary";
mode = "determinate";
value = 50.25890809809;
socket = 'http';
constructor(private http: HttpClient) {}
ngOnInit() {
}
goToLink(url: string){
window.open(url, "_blank");
}
onFileSelect(event) {
this.selectedFile = event.target.files[0];
this.name = this.selectedFile.name;
console.log(this.selectedFile);
}
resumableUpload() {
let fileId = `${this.selectedFile.name}-${this.selectedFile.lastModified}`;
let headers = new HttpHeaders({
"size": this.selectedFile.size.toString(),
"x-file-id": fileId,
'name': this.name
});
this.http
.get("http://localhost:3000/status", { headers: headers })
.subscribe((res: any) => {
console.log(JSON.stringify(res));
if(res.status === 'file is present'){
alert(res.status);
return;
}
let uploadedBytes = res.uploaded;
let headers2 = new HttpHeaders({
"size": this.selectedFile.size.toString(),
"x-file-id": fileId,
"x-start-byte": uploadedBytes.toString(),
'name': this.name
});
const req = new HttpRequest('POST', "http://localhost:3000/upload", this.selectedFile.slice(uploadedBytes, this.selectedFile.size +1 ),{
headers: headers2,
reportProgress: true
});
this.http.request(req)
.subscribe(
(res: any) => {
if(res.type === HttpEventType.UploadProgress){
this.uploadPercent = Math.round(100* uploadedBytes/this.selectedFile.size);
console.log(this.uploadPercent);
if(this.uploadPercent >= 100){
this.name = "";
this.selectedFile = null;
}
}else{
console.log(JSON.stringify(res));
if(this.uploadPercent >= 100){
this.name = "";
this.selectedFile = null;
}
}
},
err => {}
);
});
}
}
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const fs = require('fs');
const socket = require('socket.io');
const socketUpload = require('./app.js')
const app = express();
app.use(cors({origin: '*'}));
app.use(bodyParser.urlencoded({ extended: true }));
const server = app.listen(3000,() => {
console.log('Started in 3000');
});
const io = socket(server);
io.sockets.on('connection', (socket) => {
console.log(`new connection id: ${socket.id}`);
socketUpload(socket);
});
let uploads = {};
app.post('/upload', (req, res, next) => {
let fileId = req.headers['x-file-id'];
let startByte = parseInt(req.headers['x-start-byte'], 10);
let name = req.headers['name'];
let fileSize = parseInt(req.headers['size'], 10);
console.log('file Size',fileSize, fileId, startByte);
if(uploads[fileId] && fileSize == uploads[fileId].bytesReceived){
res.end();
return;
}
console.log(fileSize);
if (!fileId) {
res.writeHead(400, "No file id");
res.end(400);
}
console.log(uploads[fileId]);
if (!uploads[fileId])
uploads[fileId] = {};
let upload = uploads[fileId];
let fileStream;
if(!startByte){
upload.bytesReceived = 0;
let name = req.headers['name'];
fileStream = fs.createWriteStream(`./name/${name}`, {
flags: 'w'
});
}else{
if (upload.bytesReceived != startByte) {
res.writeHead(400, "Wrong start byte");
res.end(upload.bytesReceived);
return;
}
// append to existing file
fileStream = fs.createWriteStream(`./name/${name}`, {
flags: 'a'
});
}
req.on('data', function(data) {
//console.log("bytes received", upload.bytesReceived);
upload.bytesReceived += data.length;
});
req.pipe(fileStream);
// when the request is finished, and all its data is written
fileStream.on('close', function() {
console.log(upload.bytesReceived, fileSize);
if (upload.bytesReceived == fileSize) {
console.log("Upload finished");
delete uploads[fileId];
// can do something else with the uploaded file here
res.send({'status': 'uploaded'});
res.end();
} else {
// connection lost, we leave the unfinished file around
console.log("File unfinished, stopped at " + upload.bytesReceived);
res.writeHead(500, "Server Error");
res.end();
}
});
// in case of I/O error - finish the request
fileStream.on('error', function(err) {
console.log("fileStream error", err);
res.writeHead(500, "File error");
res.end();
});
});
app.get("/", (req, res) => {
res.send(
`<h1 style='text-align: center'>
Wellcome to FunOfHeuristic
<br><br>
<b style="font-size: 182px;">😃👻</b>
</h1>`
);
});
app.get('/status', (req, res) =>{
//console.log('came');
let fileId = req.headers['x-file-id'];
let name = req.headers['name'];
let fileSize = parseInt(req.headers['size'], 10);
console.log(name);
if(name){
try{
let stats = fs.statSync('name/' + name);
if(stats.isFile())
{
console.log(`fileSize is ${fileSize} and already uploaded file size ${stats.size}`);
if(fileSize == stats.size){
res.send({'status': 'file is present', "uploaded" : stats.size})
return;
}
if(!uploads[fileId])
uploads[fileId] = {}
console.log(uploads[fileId]);
uploads[fileId]['bytesReceived'] = stats.size;
console.log(uploads[fileId], stats.size);
}
}catch(er){
}
}
let upload = uploads[fileId];
if(upload)
res.send({"uploaded" : upload.bytesReceived});
else
res.send({"uploaded" : 0});
});
Source Code: https://github.com/funOfheuristic/ResumableFileUploader
Subscribe: https://www.youtube.com/channel/UCsy12h-0xK_UCJDIDDEe0zQ
#node.js #angular.js #angular #javascript #express