Angular nodejs Getting an Error in adding file - node.js

Hello I'm trying to add a new file using Angular and Nodejs into my mongodb database
The backend function works fine on postman
But on the frontend it gives me an error and i didnt figure out what's the problem
It used to work up until I made some changes in the backend function
this is my POST API
router.post('/create',multer({ storage : storage}).any(), (req, res) => {
var sample = fs.readFileSync('./uploads/'+req.files[0].filename,'utf8');
function Filetostring(){
let arr = sample.split(/\r?\n/);
// Find returns the first element that matches our criteria
const step = arr.filter((step , idx)=> {
if (step.includes("step")) {
console.log(step); //this gives me the first result I need
return true;
}
return false;
});
let stepss = JSON.stringify(step)
let newString = stepss.replace(/[\[\]\'\s]/g, ' ');
let newString2 = newString.replace(/"/g, '');
let newString3 = newString2.replace(/#step/g, '');
let newString4 = newString3.replace(/,/g, '\n');
return newString4;
}
let steps = Filetostring()
console.log(steps)
var tc = new Testcase({
name: req.body.name,
upload: req.files[0].filename ,
run : steps,
modify: req.body.modify,
delete: req.body.delete,
step1: req.body.step1,
step2: req.body.step2,
step3: req.body.step3,
step4: req.body.step4,
step5: req.body.step5,
step6: req.body.step6,
step7: req.body.step7,
});
console.log(req.files[0].filename);
tc.save((err, doc) => {
if (err) { res.status(401).send("errorrrrr") }
else {
res.status(200).send(doc)
}
});
});
This is my service.ts
private create = 'http://localhost:5555/testcase/create';
postTestCase(testcase,file:File) {
const formData = new FormData();
formData .append('file', file);
formData .append('name', testcase.name);
formData .append('step1', testcase.step1);
formData .append('modify', testcase.modify);
formData .append('run', testcase.run);
formData .append('delete', testcase.delete);
formData .append('step2', testcase.step2);
formData .append('step3', testcase.step3);
formData .append('step4', testcase.step4);
formData .append('step5', testcase.step5);
formData .append('step6', testcase.step6);
formData .append('step7', testcase.step7);
return this.http.post<any>(this.create, formData );
}
this is my component.ts
addtestcaseData = {'name': '',
'step1': '',
'modify': '',
'run': '',
'delete': '',
'upload': File = null,
'step2': '',
'step3': '',
'step4': '',
'step5': '',
'step6': '',
'step7':''}
addtestcase(){
this.testcaseService.postTestCase(this.addtestcaseData,this.addtestcaseData.upload)
.subscribe(
res => {
console.log(res)
this._router.navigate(['/admin'])
},
err => {
console.log(err);
}
)
};
handleFileInput(files: FileList) {
this.addtestcaseData.upload = files.item(0);
}
And this is my component.html
<div class="card rounded-0">
<div class="card-header">
<h3 class="mb-0">Add Test Case</h3>
</div>
<div class="card-body">
<form class="form" #testcaseForm="ngForm" enctype="multipart/form-data" >
<div class="form-group">
<label for="uname1">Name</label>
<input [(ngModel)]="addtestcaseData.name" class="form-control rounded-0" name="Name" type="text" required>
</div>
<div class="form-group">
<label for="file" class="mr-2">Upload Test Case</label>
<input type="file"
id="file" name="file"
(change)="handleFileInput($event.target.files)">
<!--<button (click)="addfile()" type="button" class="btn btn-success float-right">Add File</button>
-->
</div>
<button (click)="addtestcase()" type="button" class="btn btn-success float-right">Add</button>
</form>
</div>
<!--/card-block-->
</div>

Try to get file with req.file
var tc = new Testcase({
name: req.body.name,
upload: req.file,
run : steps,
modify: req.body.modify,
delete: req.body.delete,
step1: req.body.step1,
step2: req.body.step2,
step3: req.body.step3,
step4: req.body.step4,
step5: req.body.step5,
step6: req.body.step6,
step7: req.body.step7,
});
console.log(req.files[0].filename);
And for route
router.post('/create',multer({ storage : storage}).single('upload'), (req, res) => {
For frontend change the name of input to
<input type="file"
id="file" name="upload"
(change)="handleFileInput($event.target.files)">

Related

how to post form data to the server backend

Form.js
import "./form.css";
import React, {useEffect,useState} from "react";
import {addBeauty,deleteB} from "./beauty";
import Modal from "./Modal";
import axios from 'axios';
export default function CreateForm() {
const [Name, setName] = useState("");
const [Intro, setIntro] = useState("");
const [isOpen, setIsOpen] = useState();
const [backendData, setBackendData] = useState([{}]);
useEffect(()=>{
fetch("http://localhost:5000/api").then(
response=>response.json()
).then(
data=>{ setBackendData(data)}
)
},[]);
const handleSubmit = (event)=>{
event.preventDefault();
axios.post("http://localhost:5000/api",{
id: userList[userList.length - 1].id + 1, Name:Name, Introduction:Intro
}).then(res=>{
console.log(res.data);
})
}
return (
<div className="container">
<form className="add" onSubmit={handleSubmit} >
<h2>User</h2>
<label htmlFor= "name">Name</label>
<input type="text" value={Name}
onChange={(event) => {setName(event.target.value);}}/>
<label htmlFor= "Intro">Introduction</label>
<input type="text" value={Intro}
onChange={(event) => {setIntro(event.target.value);}}/>
<p></p>
<p></p>
<div className = "press">
<button id = "1" type="submit">
Add Beauty
</button>
<button id = "2"
onClick={clearForm}
>
Clear Form
</button>
</div>
</form>
<br></br>
<br></br>
<br></br>
<div className="display">
{(typeof userData.user1 === 'undefined')?(
<h1>Loading</h1>):(
backendData.user1.map((user,i)=>{
return (
<div>
<h1> {user.Name}</h1>
<button onClick={()=>{
setIsOpen(user.id);
}}>View in popup</button>
<Modal open={isOpen === user.id} onClose={()=>setIsOpen(undefined)}>
<h3> {User.Introduction}</h3>
</Modal>
</div>
);})
)}
</div>
</div>
);
}
Server.js
const express = require('express');
const app = express();
const cors=require("cors");
const corsOptions ={
origin:'*',
credentials:true, //access-control-allow-credentials:true
optionSuccessStatus:200,
}
app.use(cors(corsOptions)) // Use this after the variable declaration
app.get("/api",(req,res)=> {
res.json({"user1":[
{
id: 1,
Name: "Isabella",
},
{
id:2,
Name: "Catalina
}
]})
});
app.listen(5000,()=>{
console.log("Server started on port 5000");
})
I create a from using react. And I try to send the formdata to backend and insert the formdata into the data stored at backend using axios.post. But it doesn't work. I know it's because I didn't add the prefix of backend data "user1" in axios.post. But I am not sure how to do that. Could anyone help me with this?
You have not created the route on the server correctly. You have opened a route for GETting "/api" but you need to open a route for POSTing
Replace this line:
app.get("/api",(req,res)=> {
with
app.post("/api",(req,res)=> {
Hi Here you need to create one route for post API as below
app.post("/api",(req,res)=> {
console.log(req.body) //here you got the requested data.
res.send("Success !");
});

File upload (with other inputs and textarea) using Angular 13 and Node Js

I am trying to upload files to server using Angular and Node, using multer.
I have Todo Model as :
export class TodoModel {
todo_id !:number;
todo_title !:string;
todo_description !:string;
todo_status !:number;
todo_deleted_flag !:boolean;
todo_image !:Object;
}
todo.component.ts
title:string;
desc:string;
selected_image:File = null;
fileUploadListener(event){
//console.log(event)
//console.log(event.target.files[0])
this.selected_image = <File>event.target.files[0]
console.log(this.selected_image)
}
onSubmit(form:NgForm){
const fd = new FormData()
if(this.selected_image) {
fd.append('todo_image',this.selected_image,this.selected_image.name)
}
console.log(fd);
const todo_model : TodoModel = {
todo_id: null,
todo_title:this.title,
todo_description:this.desc,
todo_status:1,
todo_deleted_flag:false,
todo_image:null
}
console.log(fd);
this.todoAdd.emit(todoadded);
this.todoAdd_DB.emit(todo_model);
this.addTodo_DB(todo_model, fd)
form.resetForm();
}
addTodo_DB(todo_db: TodoModel, fileUpload:Object){
//const todo_db
return this.http.post<{message:any}>('http://localhost:3000/api/todos/post_all_todos_db', todo_db,fileUpload).subscribe(data => {
console.log(data.message);
console.log(todo_db);
})
}
todo.component.html
<div class="col-md-12">
<form (ngSubmit)="onSubmit(todoForm)" #todoForm="ngForm">
<div class="mb-3">
<label for="todo_title" class="form-label">Title</label>
<input type="text" class="form-control" id="todo_title" [(ngModel)]="title" name="title">
</div>
<div class="mb-3">
<label for="label" class="form-label">Description</label>
<textarea class="form-control" id="todo_description" [(ngModel)]="desc" name="desc"></textarea>
</div>
<div class="mb-3">
<label for="todo_image" class="form-label">Image</label>
<input type="file" class="form-control" id='todo_image' (change)="fileUploadListener($event)">
</div>
<button type="submit" class="btn btn-success">Add To Do</button>
</form>
</div>
</div>
And on Server Side, using Node Js and PgSQL :-
app.post('/api/todos/post_all_todos_db',upload_using_multer.single('todo_images') , (req, res, next) => {
// const todo_post = req.body;
const files = req.file;
console.log(files) // - ----------> This does NOT work
console.log(req.body) //------> this works
//PGSQL insert query here
res.status(201).json({
message:"Post Added Successfully"
})
})
While doing console.log() in Angular side, I am getting the form data, but, on Node Js side, I get it as null.
Almost every tutorial I see, uses only one file upload , and that too, try to submit the form using the Form's action. I dont want to do that, so I tried doing this.
I
i once had the same issue and solved it with formdata, my example uploads multiple files. here is an example:
Node.JS
const serverRoutes = (function () {
const express = require('express');
const router = express.Router();
const multer = require('multer');
const upload = multer();
router.post('/myresource', upload.any(), (req, res) => {
console.log(req.files);
});
return router;
});
on angular
export class DataService {
constructor(private http: HttpClient) { }
sendMyFiles(file): Observable<MyResponse> {
const formData = new FormData();
formData.append("file", file);
return this.http.post<MyResponse>(
`${environment.backendAPI}myresource`,
formData
);
}
}

PayloadTooLargeError: request entity too large when upload image

I am trying to upload/and save an image in base64 format to my mongo database.
If I use a very very small image it works, but I try to use an image of 161 kb, I have this error:
PayloadTooLargeError: request entity too large
So I try to convert my image with Json but I got an error or it doesn't work,
Her my code ( I am using vue):
<template>
<div class="profile">
<div class="px-4">
<div class="row justify-content-center">
<div class="col-lg-3 order-lg-2">
<div class="card-profile-image image-preview">
<div v-if="profImage !=undefined && profImage.length > 0">
<a>
<img
:src="profImage"
class="rounded-circle"
/>
</a>
</div>
<div>
<div class="file-upload-form">
Upload image:
<input
type="file"
#change="previewImage"
accept="image/*"
/>
</div>
<div class="image-preview" v-if="imageData.length > 0">
<img class="preview" :src="imageData" />
<button #click="updateUserImage"></button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
Here my js file:
<script>
import DataService from '#/services/DataService'
export default {
name: 'Profile',
data: function() {
return {
username: '',
imageData: '',
profImage: '',
}
},
methods: {
previewImage: function(event) {
var input = event.target
if (input.files && input.files[0]) {
var reader = new FileReader()
reader.onload = e => {
this.imageData = e.target.result
}
reader.readAsDataURL(input.files[0])
}
},
async getAllInfo() {
var userImage = await DataService.getUserImage({
username: this.username
})
this.profImage = userInfo.data.user[0].profImage //IT Works
this.profImage = JSON.parse(userInfo.data.user[0].profImage) //I get an error
},
async updateUserImage() {
var temp = JSON.stringify(this.imageData)
console.log(this.firstname)
await DataService.updateUserInfo({
username: this.username,
user: {
profImage: temp
}
})
}
},
mounted() {}
}
</script>
When I try to use "JSON.parse(userInfo.data.user[0].profImage)"I get an error :
"Unexpected token d in JSON at position 0"
I also try with JSON.Stringify, but I get is not a function.
In my db, the image is saved in this way:
profImage: {
image: Buffer,
require: false
},
What am I doing wrong? I am using mongodb, vue , express and node.
I change the parser limit using
bodyParser.json({ limit: "50mb" })
and works for me

Save file to mongodb using angular and Nodejs

I am trying to upload an image to mongodb using angular and nodejs. The code is below. I got the backend working but the problem is with the html input i get 'C:fakepath/file.xyz'. I was looking online and saw that there is not a way to get the relative path of the file. Can someone please tell me how i can change my front end code to get and send the file path to the backend to then save. I read that the browser doesnt allow relative path of the file but then how can I upload. Thanks!
The nodejs image save method is:
async function SaveImage(userParam) {
const entry = new imageEntries(userParam);
entry.image.data = fs.readFileSync(userParam.imagePath);
entry.image.contentType = 'image/png';
await entry.save();
}
The html code is:
<div class="upload-btn-wrapper">
<button class="btn">Upload a file</button>
<input type="file" name="myfile" id="myFile" />
</div>
What I pass as the path in the backend is:
ImageJournal.imagePath = (<HTMLInputElement>document.getElementById('myFile')).value;
but with the code above i get the following error:
ENOENT: no such file or directory, open 'C:\fakepath\chapter9problemsandanswers.doc'
Ok here it is:
HTML:
<div class="form-group">
<label for="pdf">PDF</label>
<input type="file" id="pdf" (change)="onFileChange($event)" #fileInput>
<button type="button" class="btn btn-sm btn-default" (click)="clearFile()">clear file</button>
</div>
TS:
import { Component, OnInit, ElementRef, ViewChild } from '#angular/core';
#ViewChild('fileInput') fileInput: ElementRef;
public image;
onFileChange(event) {
let reader = new FileReader();
if(event.target.files && event.target.files.length > 0) {
let file = event.target.files[0];
reader.readAsDataURL(file);
let value = <String>reader.result;
reader.onload = () => {
this.image = {
filename: file.name,
filetype: file.type,
value: value.split(',')[1]
};
};
}
}
Then send the image with http post with a service.
On the server:
// send file
app.post('/api/sendFile', function (req, res) {
File.create({
filename: req.body.filename,
filetype: req.body.filetype,
value: req.body.value
}, function (err, file) {
if (err)
res.send(err);
else {
const response = {
name: file.filename
}
res.send(response);
}
});
});
This is written with mongoDb and mongoose and I have a model named File.
This is all it need to save it.

How to send a large datauri of an image to express server

I have the daturi of an image which is uploaded from the desktop.I would like to send this data uri to express server so as to save the dataUri in a text file. Since the size of the data uri of the image is quite large I am getting payload too large error which is understandable. I tried using multer but I couldn't figure out how to extract the data uri of the image when multer is used, on the server side.Any help on this is greatly appreciated.
Below is some of the code sample that I am trying to use
<div class="row">
<div class="form-group">
<label class="btn btn-default btn-file" for="FileUpload">Upload a Plan</label>
<input type="file" id ="FileUpload" accept="image/*" capture="camera" value="" onchange="readFileURL(this);" style="display: none;">
<img id="chosenFile" src="#" style="visibility: hidden;"/>
</div>
</div>
<div class="row">
<div class="col-sm-12"><button style="background-color: green" class="btn btn-default btn-sm" onclick="handleUplod(this)">Upload</button></div>
</div>
<script type="text/javascript">
function readFileURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
document.getElementById("chosenFile").style.visibility="visible";
reader.onload = function (e) {
$('#chosenFile').attr('src', e.target.result).width(150).height(150);
console.log("result:",e.target.result);
imageData = e.target.result;
};
console.log("data url:"+reader.readAsDataURL(input.files[0]));
}
};
function handleUplod(){
$.ajax({
type: "POST",
url: "/send",
data: { MyPlanDataUri:imageData },
success: function(result){
location.href= "/someplace";
},
error: function(result) {
alert('error');
}
});
};
On the server side I am doing the following
app.post('/send', function(req,res) {
var Tex1 = req.body.MyPlanDataUri;
var newFile = "ImageFile.txt";
fs.writeFile(newFile, Tex1, (err) => {
if (err) res.send(err);
console.log('File saved successfully ! - ', newFile);
}
);
res.send("Successfull");
}
P.S the above code works perfectly fine for small datauri's

Resources