How upload image in angular 7 from backend - node.js

i can upload image with postman but in angular it doesn't work for me. solution please
error : cannot read originalname of undefined , in nodejs but with
postman its work !
//backend
var express = require("express")
var router = express.Router();
var userModel = require("../models/userModel")
const jwt= require("jsonwebtoken")
const bcrypt=require("bcrypt")
var app=express()
var io = require('socket.io-client')('http://localhost:3000/alll')
var socket = require("socket.io");
var fs=require("fs")
var multer=require("multer")
const upload = multer({dest: __dirname + '/upload/images'});
router.post('/uploads', upload.single('image'), function (req, res) {
var file = __dirname + '/upload' + req.file.originalname;
fs.readFile(req.file.path, function (err, data) {
fs.writeFile(file, data, function (err) {
if (err) {
console.error(err);
var response = {
message: 'Sorry, file couldn\'t be uploaded.',
filename: req.file.originalname
};
} else {
response = {
message: 'File uploaded successfully',
filename: req.file.originalname
};
res.json(response);
}
})
})
})
router.post("/add",function (req, res) {
user = new userModel({firstName: req.body.firstName,
lastName: req.body.lastName ,
email:req.body.email ,
password:req.body.password,
adresse:req.body.adresse,
verif:'1',role :'user',
annonces:req.body.annonces,
pdf: req.body.pdf
})
user.save(function(err) {
if (err) {
res.send({"state": "not ok", "msg": "err:" + err})
} else {
res.send({"state": " ok", "msg": "ajout"})
}
})
})
// model : pdf as String
//ts
import {ChangeDetectorRef, Component, OnInit, TemplateRef} from '#angular/core';
import {FormBuilder, FormGroup, Validators} from '#angular/forms';
import {Router} from '#angular/router';
import {UserService} from '../services/user.service';
import {ConnecterComponent} from '../connecter/connecter.component';
import {BsModalRef, BsModalService} from 'ngx-bootstrap/modal';
import { FileUploader } from 'ng2-file-upload';
#Component({
selector: 'app-singin',
templateUrl: './singin.component.html',
styleUrls: ['./singin.component.css']
})
export class SinginComponent implements OnInit {
registrationForm: FormGroup;
submit = false;
fileSelected: File
emailuser: String;
modalRef: BsModalRef;
selectedFiles: FileList;
currentFileUpload: File;
imgURL: any;
imgname;
errorValidImage = '';
URL ='http://localhost:3000/users/uploads';
constructor(private router: Router, private userService: UserService, private formbuilder: FormBuilder , private cd : ChangeDetectorRef, private modalService: BsModalService ) { }
ngOnInit() {
this.registrationForm = this.formbuilder.group({
email: [ '', [ Validators.required, Validators.email]],
password: ['', [ Validators.required, Validators.minLength(8)]],
firstName:['',[ Validators.required]],
lastName: ['', Validators.required],
adresse:['', Validators.required],
pdf:[''],
});
}
get f() {
return this.registrationForm.controls;
}
OnSubmit(){
this.submit = true;
if (this.registrationForm.invalid) {
return;
}
console.log(this.registrationForm.value)
localStorage.setItem('var', '1');
this.userService.updateimagee(this.currentFileUpload).subscribe(res=>{
this.imgname=JSON.parse(JSON.stringify(res['filename']));
this.userService.register(this.registrationForm.value.firstName,this.registrationForm.value.lastName,this.registrationForm.value.email,this.registrationForm.value.password,this.registrationForm.value.adresse,this.registrationForm.value.pdf=this.imgname).subscribe( res => {
console.log(res['status'])
});
this.userService.login(this.registrationForm.value.email,this.registrationForm.value.password).subscribe(res=>{
localStorage.setItem('var', '1')
localStorage.setItem('emailuser',JSON.parse(JSON.stringify(res['data'])).email)
this.emailuser=localStorage.getItem('emailuser')
console.log(res['status'])
console.log(JSON.parse(JSON.stringify(res['data'])).token);
// console.log(JSON.parse(JSON.stringify(res['data'])).id);
var iduser = parseInt(JSON.parse(JSON.stringify(res['data'])).id);
sessionStorage.setItem('id', JSON.parse(JSON.stringify(res['data'])).id);
this.router.navigate(['']);
})
})
}
selectFile(event) {
this.selectedFiles =event.target.files;
this.currentFileUpload = this.selectedFiles.item(0);
console.log(this.currentFileUpload);
const reader = new FileReader();
reader.onload = (event) => {
this.imgURL = reader.result;
};
console.log(this.imgURL);
console.log(reader);
} }
//html
<div class="container">
<form method="POST" class="appointment-form" id="appointment-form" [formGroup]="registrationForm" (ngSubmit)="OnSubmit()" enctype="multipart/form-data">
<h2>education appointment form</h2>
<div class="form-group-1">
<div [class]="form-control" >
<input type="text" class="form-control" formControlName="firstName" placeholder="First Name" [ngClass]="{'is-invalid':submit && f.firstName.errors} " />
<span class="focus-input100" data-placeholder=""></span>
<div *ngIf="submit && f.firstName.errors" class="invalid-feedback">
<div *ngIf="f.firstName.errors.required">firstName is required </div>
</div>
</div>
<div [class]="form-control" >
<input type="text" formControlName="lastName" placeholder="Last Name" class="form-control" [ngClass]="{'is-invalid':submit && f.lastName.errors}" />
<div *ngIf="submit && f.lastName.errors" class="invalid-feedback">
<div *ngIf="f.lastName.errors.required">LastName is required </div>
</div>
</div>
<div [class]="form-control" >
<input type="email" formControlName="email" placeholder="Email" class="form-control" [ngClass]="{'is-invalid':submit && f.email.errors}" />
<div *ngIf="submit && f.email.errors" class="invalid-feedback">
<div *ngIf="f.email.errors.required">Email is required </div>
</div>
</div>
<div [class]="form-control" >
<input type="password" formControlName="password" placeholder="Password" class="form-control" [ngClass]="{'is-invalid':submit && f.password.errors}" />
<div *ngIf="submit && f.password.errors" class="invalid-feedback">
<div *ngIf="f.password.errors.required">Password is required </div>
<div *ngIf="f.password.errors.minlength">Au moins 8 caracteres </div>
</div>
</div>
<div [class]="form-control" >
<input type="text" formControlName="adresse" placeholder="Adresse local" class="form-control" [ngClass]="{'is-invalid':submit && f.adresse.errors}" />
<div *ngIf="submit && f.adresse.errors" class="invalid-feedback">
<div *ngIf="f.adresse.errors.required">Adresse is required </div>
</div>
</div>
<div class="custom-file">
<input type="file" class="custom-file-input" id="customFile" (change)="selectFile($event)" formControlName="pdf" [ngClass]="{'is-invalid':submit && f.pdf.errors}" />
<label class="custom-file-label">Photo de profil</label>
</div>
<div class="form-submit">
<input type="submit" name="submit" id="submit" class="submit" value="Submit" />
</div>
</div>
</form>
</div>
</div>
but console say that there is error in back-end that :
TypeError: Cannot read property 'originalname' of undefined
at C:\Users\hazem\Desktop\pfe\router\user.js:114:47

It seems like you have not used the library ng2-file-upload Try something like this.
import { Component, OnInit } from '#angular/core';
import { FileUploader, FileSelectDirective } from 'ng2-file-upload/ng2-file-upload';
const UploadURL = 'http://localhost:3000/api/upload';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'Upload a File';
public uploader: FileUploader = new FileUploader({url: URL, itemAlias: 'image'});
ngOnInit() {
this.uploader.onAfterAddingFile = (file) => { file.withCredentials = false; };
this.uploader.onCompleteItem = (item: any, response: any, status: any, headers: any) => {
console.log('FileUpload:uploaded:', item, status, response);
alert('File uploaded successfully');
};
}
}
The line
public uploader: FileUploader = new FileUploader({url: URL, itemAlias: 'image'});
is important. make sure you use the same name('image') in you multer middleware,
like this
upload.single('image')

Related

Warning: Each child in a list should have a unique "key" prop and does not save in my json-server

I keep getting error "Warning: Each child in a list should have a unique "key" prop" on console log. I think there is something wrong in the
axios.delete('http://localhost:3000/contacts/${id}
' or
axios.put('http://localhost:3000/contacts/${isUpdate.id}'
It works, but does not configure in the json-server that I made. So the changes does not happen in the json-server.
The "save" button works, and added new data into my json-server. But, when I tried to edit, or delete, it does not save the changed in json-server.
My code:
import "./App.css";
import List from "./List";
import { useState,useEffect } from "react";
import {uid} from "uid";
import axios from "axios";
function App() {
const [contacts, setContacts] = useState([]);
function handleChange(e) {
let data = { ...formData };
data[e.target.name] = e.target.value;
setFormData(data);
}
const [isUpdate, setIsUpdate] = useState({ id: null, status: false});
const [formData, setFormData] = useState({
name: "",
telp: "",
});
useEffect(() => {
axios.get("http://localhost:3000/contacts").then((res) => {
console.log(res.data);
setContacts(res?.data ?? []);
});
}, []);
function handleSubmit(e){
e.preventDefault();
alert("Oke Bos!");
let data = [...contacts];
if(formData.name === "") {
return false;
}
if(formData.telp === "") {
return false;
}
if ( isUpdate.status){
data.forEach((contact) => {
if (contact.id === isUpdate.id) {
contact.name = formData.name;
contact.telp = formData.telp;
}
});
axios.put('http://localhost:3000/contacts/${isUpdate.id}', {
name: formData.name,
telp: formData.telp,
})
.then((res) => {
alert("Berhasil edit data!");
});
} else {
let newData = { id: uid(), name: formData.name, telp: formData.telp };
data.push(newData);
axios.post("http://localhost:3000/contacts", newData).then((res) => {
alert("Data telah disimpan cok!");
});
}
// tambah kontak yee
setIsUpdate({id: null, status: false});
setContacts(data);
setFormData({ name: "", telp: ""});
}
function handleEdit(id) {
let data = [...contacts];
let foundData = data.find((contact) => contact.id === id);
setFormData({ name: foundData.name, telp: foundData.telp});
setIsUpdate({id: id, status: true});
}
function handleDelete(id) {
let data = [...contacts];
let filteredData = data.filter((contact) => contact.id !== id);
axios.delete('http://localhost:3000/contacts/${id}').then((res) => {
alert("Data telah dihapus");
});
setContacts(filteredData);
}
return (
<div className="App">
<h1 className="px-3 py-3">My Contact List</h1>
<form onSubmit={handleSubmit} className="px-3 py-4">
<div className="form-group">
<label htmlFor="">Name</label>
<input type="text"
className="form-control"
onChange={handleChange}
value={formData.name}
name="name" />
</div>
<div className="form-group mt-3">
<label htmlFor="">No. Telp</label>
<input type="text"
className="form-control"
onChange={handleChange}
value={formData.telp}
name="telp" />
</div>
<div>
<button type="submit" className="btn btn-primary w-100 mt-3">
Save
</button>
</div>
</form>
<List handleDelete={handleDelete} handleEdit={handleEdit} data={contacts} />
</div>
);
}
export default App;
The list component:
import React from "react";
export default function List({data,handleEdit,handleDelete}) {
return (
<div className="list-group">
{
data.map((contact) => {
return (
<div className="list-group-item list-group-item-action">
<div className="d-flex w-100 justify-content-between">
<h5 className="mb-1">{contact.name}</h5>
<div>
<button onClick={() => handleEdit(contact.id)} className="btn btn-sm btn-link">Edit</button>
<button onClick={() => handleDelete(contact.id)} className="btn btn-sm btn-link">Del</button>
</div>
</div>
<p className="mb-1">{contact.telp}</p>
</div>
);
})}
</div>
);
}
I follow the tutorial, the code is like this, i checked it in so many times. But still it does not configure well into json-server like what i see on youtube.

request body empty when send form data to node js rest API

I created an HTML form to store data into MSSQL
This is the form:
<form [formGroup]="insProtocolloForm" (ngSubmit)="sumit()" enctype="multipart/form-data">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="newProtInStaticBackdropLabel">Nuovo protocollo in entrata</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="form-group">
<label for="dataEmissione">Data Emissione</label>
<input formControlName="dataEmissione" id="dataEmissione" name="dataEmissione" type="text" class="form-control" />
</div>
<div class="form-group">
<label for="anno">Anno</label>
<input formControlName="anno" id="anno" name="anno" type="text" class="form-control" />
</div>
<div class="form-group">
<label for="sede">Sede</label>
<input formControlName="sede" id="sede" name="sede" type="text" class="form-control" />
</div>
<div class="form-group">
<label for="entrataUscita">#Entrata Uscita</label>
<input formControlName="entrataUscita" id="entrataUscita" name="entrataUscita" type="text" class="form-control" />
</div>
<div class="form-group">
<label for="fileToUpload">File</label>
<input formControlName="fileToUpload" id="fileToUpload" name="fileToUpload" type="file" class="form-control" (change)="onFilechange($event)" />
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Annulla</button>
<button type="submit" class="btn btn-success">Inserisci</button>
</div>
</div>
</div>
</form>
And this is the component.ts
import { Component, OnInit } from '#angular/core';
import { CrudService } from '../service/crud.service';
import { DatePipe } from '#angular/common'
import { HttpClient } from '#angular/common/http';
import { FormGroup, FormControl, Validators} from '#angular/forms';
#Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {
insProtocolloForm = new FormGroup({
dataEmissione: new FormControl('', [Validators.required]),
anno: new FormControl('', [Validators.required]),
sede: new FormControl('', [Validators.required]),
entrataUscita: new FormControl('', [Validators.required]),
fileToUpload: new FormControl('', [Validators.required]),
fileSource: new FormControl('', [Validators.required])
});
constructor(private crudService: CrudService, private http: HttpClient) { }
get f(){
return this.insProtocolloForm.controls;
}
onFilechange(event: any) {
//console.log(event.target.files[0])
if (event.target.files.length > 0) {
const fileToUpload = event.target.files[0];
this.insProtocolloForm.patchValue({
fileSource: fileToUpload
});
}
}
sumit() {
console.log('### INIZIO SUBMIT() ###');
const formData = new FormData();
formData.append('dataEmissione', this.insProtocolloForm.get('dataEmissione')?.value);
formData.append('anno', this.insProtocolloForm.get('anno')?.value);
formData.append('sede', this.insProtocolloForm.get('sede')?.value);
formData.append('entrataUscita', this.insProtocolloForm.get('entrataUscita')?.value);
formData.append('fileToUpload', this.insProtocolloForm.get('fileSource')?.value);
console.log(formData);
if (this.insProtocolloForm.get('fileSource')?.value) {
this.http.post('http://localhost:8090/api/inserisci-protocollo', formData)
.subscribe(res => {
console.log('res: ' + res);
alert('Uploaded Successfully.');
});
} else {
alert("Si prega di scegliere un file da caricare")
}
console.log('### FINE SUBMIT() ###');
}
ngOnInit(): void { }
}
On submit I call the Node JS REST API
const sqlController = require('./controllers/dboperations-sql');
const express = require('express');
const cors = require('cors');
const multer = require('multer');
const storage = multer.memoryStorage()
const upload = multer({ storage: storage })
const app = express();
const router = express.Router();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cors());
app.use('/api', router);
app.use(upload.single());
router.use((request,response,next)=>{
next();
})
//Inserisco un nuovo protocollo -> /inserisci-protocollo
router.route('/inserisci-protocollo').post((request,response)=>{
console.log('### Requested: Insert new Protocol ###');
/*request.on('data', data => {
console.log(data.toString());
});*/
let newProtocollo = request.body;
//console.log(newProtocollo);
sqlController.addProtocollo(newProtocollo).then(result => {
response.status(201).json(result);
})
})
And here is the problem. The request.body is always empty.
But if I enable the "request.on('data', data => {..." code, I see all form fields.
I also tried to send data with postman but I have the same result.
With postman, if I set the "form-data" option, the body is always empty, but if I set the "x-www-form-urlencoded" option I see all data except the file.
Can anyone help me to solve this problem?
I've read a lot of posts about it but haven't been able to find a solution yet.
I'm going crazy
Thank you very much
Adriano
You need to add the content type headers in the request from angular's http client.
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'multipart/form-data'
})
};
this.http.post('http://localhost:8090/api/inserisci-protocollo', formData, httpOptions)

Redirect to profile after login

I am doing google auth with passport and
I wanna redirect to the profile after successfully logged in.
The problem is my method of this.props.history.push('/profile') dont work.
By the way, it's from my router that I need to redirect the user to profile.
All the authentication is in the route.
Here is my code any suggestions?
The if (user) {} is true my only problem is on how to redirect the user.
Route:
const Strategy = require('passport-local').Strategy
const mongoose = require('mongoose')
const GoogleUser = require('../models/google');
const GoogleAuth = new Strategy(
{ passReqToCallback: true, usernameField: "email", passwordField: "id" },
function(req, email, id, done) {
GoogleUser.findOne({ email: req.body.email })
.lean()
.exec((err, user) => {
if (err) {
return done(err, null);
}
if (!user) {
let newUser = new GoogleUser({
email: req.body.email,
id: req.body.id,
name: req.body.name,
token: req.body.token,
image: req.body.image
});
newUser.save((error, inserted) => {
if (error) {
return done(error, null);
}
return done(null, inserted);
});
}
if (user) {
this.props.history.push("/profile");
}
});
}
);
module.exports = GoogleAuth;
Here is the React code if needed:
import React, { Component } from 'react';
import axios from "axios";
import {Redirect} from "react-router-dom"
import styles from '../styles/loginsignup.css'
import logo from '../img/nowyourguest.png'
import 'bootstrap/dist/css/bootstrap.min.css'
import 'jquery/dist/jquery.min.js'
import 'bootstrap/dist/js/bootstrap.min.js'
export default class Login extends Component {
componentDidMount() {
this.googleSDK();
console.log('sfsfd');
}
prepareLoginButton = () => {
console.log(this.refs.googleLoginBtn);
this.auth2.attachClickHandler(this.refs.googleLoginBtn, {},
(googleUser) => {
let profile = googleUser.getBasicProfile();
const email = profile.getEmail()
const id = profile.getId()
const name = profile.getName()
const token = googleUser.getAuthResponse().id_token
const image = profile.getImageUrl()
axios({
url: "/authentication/google",
method: "POST",
data: {
email,
id,
name,
token,
image
}
})
.then(response => {
const isAuthenticated = response.data.isAuthenticated
window.localStorage.setItem('isAuthenticated', isAuthenticated);
this.props.history.push('/profile')
})
.catch(error =>{
this.setState({
errorMessage:error.response.data.message
})
})
})
}
googleSDK = () => {
window['googleSDKLoaded'] = () => {
window['gapi'].load('auth2', () => {
this.auth2 = window['gapi'].auth2.init({
client_id: 'clientID',
cookiepolicy: 'single_host_origin',
scope: 'profile email'
});
this.prepareLoginButton();
});
}
(function(d, s, id){
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {return;}
js = d.createElement(s); js.id = id;
js.src = "https://apis.google.com/js/platform.js?onload=googleSDKLoaded";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'google-jssdk'));
}
state = {
email: '',
password: ''
};
handleSubmit = event => {
event.preventDefault();
const {email, password } = this.state;
axios({
url: "/authentication/signin",
method: "POST",
data: {
email,
password
}
})
.then(response => {
const isAuthenticated = response.data.isAuthenticated
window.localStorage.setItem('isAuthenticated', isAuthenticated);
this.props.history.push('/profile')
})
.catch(error =>{
this.setState({
errorMessage:error.response.data.message
})
})
};
handleChange = event => {
const {name, value} = event.target;
this.setState({
[name]:value
})
}
render() {
const isAuthenticated = window.localStorage.getItem('isAuthenticated');
if (isAuthenticated) {
return <Redirect to='/profile' />
}
return(
<div>
<div>
<nav className="navbar navbar-expand-lg navbar-light bg-info sticky-top" id="shadow">
<a className="navbar-brand text-warning" href="/">NowYourGuest</a>
<button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span className="navbar-toggler-icon" />
</button>
<div className="collapse navbar-collapse" id="navbarSupportedContent" >
<ul className="navbar-nav mr-auto">
<li className="nav-item">
<a className="nav-link text-white" href="/add-your-accomodation">Add your accomodation</a>
</li>
<li className="nav-item active">
<a className="nav-link" href="/login">Login<span className="sr-only">(current)</span></a>
</li>
<li className="nav-item">
<a className="nav-link text-white" href="/signup">Signup</a>
</li>
</ul>
</div>
<form className="form-inline my-2 my-lg-0">
<input className="form-control mr-sm-2" type="search" placeholder="Search for accomodation" aria-label="Search" />
</form>
</nav>
</div>
<div className="container">
<div className="card card-container">
<center><img id="profile-img" className="profile-img" src={logo} /></center>
<p id="profile-name" className="profile-name-card" />
<form onSubmit={this.handleSubmit} className="form-signin">
<span id="reauth-email" className="reauth-email" />
<input type="text" id="inputEmail" className="form-control" name="email" onChange={this.handleChange} placeholder="Email address" required autofocus />
<input type="password" id="inputPassword" className="form-control" name="password" onChange={this.handleChange} placeholder="Password" required />
<center><p style={{color: 'red'}}>{this.state.errorMessage}</p></center>
<button className="btn btn-lg btn-primary btn-block btn-signin" type="submit">Sign in</button>
</form>
<button className="loginBtn loginBtn--google" ref="googleLoginBtn">Login with Google</button>
<a href="#" className="forgot-password">
Forgot the password?
</a>
</div>
</div>
</div>
)
}
}
module.exports = Login;
you need to use "withRouter" from "react-router-dom".
All you need to do is import withRouter and wrap your component at export:
import { withRouter } from "react-router-dom";
//.
//.
//.
export default class (withRouter(Login))
You can also use Redirect component from "react-router-dom" and return it instead
import { Redirect } from "react-router-dom";
// Your code
render() {
if (User) {
return <Redirect to={"/route"} />
}
return(
// If user is not logged...
)
}
I just made 2 different routes in one login and one register.
And it perfectly works.

Unable to display flsha-messages when form is submitted

I'm using nodejs, Express and angular 6 for my website, and I've just created a contact form with nodemailer. Now I want to use a flash message to show on the contact page after the form is submitted eg
Data succesfully submitted ! Thanks' and vice versa
here is form
<h1>Contact us</h1>
<flash-messages></flash-messages>
<form [formGroup]="angForm" method="POST" novalidate>
<div class="message">
<h3> Write to us </h3>
</div>
<div class="form__top">
<div class="form__left">
<div class="form__group">
<input class="form__input form__input--name" type="text" formControlName="name" placeholder="name" #name>
</div>
<div *ngIf="angForm.controls['name'].invalid && (angForm.controls['name'].dirty || angForm.controls['name'].touched)" class="alert alert-danger">
<div *ngIf="angForm.controls['name'].errors.required">
Name is required.
</div>
</div>
<div class="form__group">
<input class="form__input form__input--email" type="email" formControlName="email" placeholder="email" #email>
</div>
<div *ngIf="angForm.controls['email'].invalid && (angForm.controls['message'].dirty || angForm.controls['message'].touched)"
class="alert alert-danger">
<div *ngIf="angForm.controls['message'].errors.required">
message is required.
</div>
</div>
</div>
<div class="form__right">
<div class="form__group">
<textarea class="form__input form__input--textarea" placeholder="Message" formControlName="message" #message
rows="3"></textarea>
</div>
<div *ngIf="angForm.controls['message'].invalid && (angForm.controls['message'].dirty || angForm.controls['message'].touched)"
class="alert alert-danger">
<div *ngIf="angForm.controls['message'].errors.required">
message is required.
</div>
</div>
</div>
</div>
<div class="form__down">
<div class="form__group">
<button (click)="sendMail(name.value, email.value, message.value)" [disabled]="angForm.pristine || angForm.invalid" class="form__input form__input--submit" name="submit" type="submit" value="SEND MESSAGE">SEND MESSAGE
</button>
</div>
</div>
</form>
here is components.ts
import { Component, OnInit } from '#angular/core';
import { ContactService } from '../../contact.service';
import { FormGroup, FormBuilder, Validators } from '#angular/forms';
import { FlashMessagesModule, FlashMessagesService } from 'angular2-flash-messages';
#Component({
selector: 'app-footer',
templateUrl: './footer.component.html',
styleUrls: ['./footer.component.scss']
})
export class FooterComponent implements OnInit {
angForm: FormGroup;
constructor(
private flashMessages: FlashMessagesService,
private fb: FormBuilder,
private contactService: ContactService) {
this.createForm();
}
createForm() {
this.angForm = this.fb.group({
name: ['', Validators.required],
email: ['', Validators.required],
message: ['', Validators.required],
});
}
sendMail(name, email, message) {
this.contactService.sendEmail(name, email, message).subscribe(() => {
this.flashMessages.show('You are data we succesfully submitted', { cssClass: 'alert-success', timeout: 3000 });
}, error => {
this.flashMessages.show('Something went wrong', { cssClass: 'alert-danger', timeout: 3000 });
});
}
ngOnInit() {
}
}
here is contact.js(node mailer settings)
const express = require('express');
const router = express.Router();
const request = require('request');
const nodemailer = require('nodemailer');
router.post('/send', (req, res) => {
const outputData = `
<p>You have a new contact request</p>
<h3>Contact Details</h3>
<ul>
<li>Name: ${req.body.name}</li>
<li>Email: ${req.body.email}</li>
</ul>
<h3>Message</h3>
<p>${req.body.message}</p>
`;
let transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'myEmail',
pass: 'pass'
},
tls: {
rejectUnauthorized: false
}
});
let HelperOptions = {
from: '"name" <myEmail',
to: 'myEmail',
subject: 'Majeni Contact Request',
text: 'Hello',
html: outputData
};
transporter.sendMail(HelperOptions, (error, info) => {
if (error) {
return console.log(error);
}
console.log("The message was sent!");
console.log(info);
});
});
module.exports = router;
Now I am able to send the message, but I want the successfully message to display when data is submitted. unfortunatelly nothing is displayed but the data is submitted.
what am I doing wrong here?
Code looks totally fine and it should work as expected, anyhow if you are using any api with node.js you can set the timeout to send the response as follows,
setTimeout((function() {res.send("ok")}), 2000);

Angular 6 + NodeJS + MongoDB

Hello after searching here i was unable to find something. 2 similar questions hasn't been answered.
im new here sos if you can help with my final project or lead me to a fix i will be more then happy.
after runing ngForm im unable to post and recive the folowing error:
zone.js:2969 POST http://localhost:4200/signup 404 (Not Found)
core.js:1624 ERROR
My form sits inside other component and my routing looks like that:
{
path: 'signup',
component: SignUpComponent,
data: { title: 'signup' },
children: [
{path: '', component: RegistrationComponent},
{path: 'userSettings', component: UserSettingsComponent},
{path: 'userSettings/finish', component: FinishComponent},
]},
Registration.Component.html
<div class="panel panel-primary">
<div class="panel-heading">
{{ test }}
</div>
<div class="panel-body">
<form [formGroup]="angForm" novalidate>
<div class="form-group">
<label class="col-md-4">inputfirstname</label>
<input type="text" class="form-control" formControlName="inputfirstname" #inputfirstname />
</div>
<div *ngIf="angForm.controls['inputfirstname'].invalid && (angForm.controls['inputfirstname'].dirty || angForm.controls['inputfirstname'].touched)" class="alert alert-danger">
<div *ngIf="angForm.controls['name'].errors.required">
Name is required.
</div>
</div>
<div class="form-group">
<label class="col-md-4">lastname</label>
<input type="text" class="form-control" formControlName="inputlastname" #inputlastname/>
</div>
<div *ngIf="angForm.controls['inputlastname'].invalid && (angForm.controls['inputlastname'].dirty || angForm.controls['inputlastname'].touched)" class="alert alert-danger">
<div *ngIf="angForm.controls['inputlastname'].errors.required">
LastName is required.
</div>
</div>
<div class="form-group">
<label class="col-md-4">inputEmail</label>
<input type="text" class="form-control" formControlName="inputEmail" #inputEmail/>
</div>
<div *ngIf="angForm.controls['inputEmail'].invalid && (angForm.controls['inputEmail'].dirty || angForm.controls['inputEmail'].touched)" class="alert alert-danger">
<div *ngIf="angForm.controls['inputEmail'].errors.required">
inputEmail is required.
</div>
</div>
<div class="form-group">
<label class="col-md-4">inputPassword</label>
<input type="text" class="form-control" formControlName="inputPassword" #inputPassword/>
</div>
<div *ngIf="angForm.controls['inputPassword'].invalid && (angForm.controls['inputPassword'].dirty || angForm.controls['inputPassword'].touched)" class="alert alert-danger">
<div *ngIf="angForm.controls['inputPassword'].errors.required">
inputPassword is required.
</div>
</div>
<div class="form-group">
<label class="col-md-4">confirmPassword</label>
<input type="text" class="form-control" formControlName="confirmPassword" #confirmPassword/>
</div>
<div *ngIf="angForm.controls['confirmPassword'].invalid && (angForm.controls['confirmPassword'].dirty || angForm.controls['confirmPassword'].touched)" class="alert alert-danger">
<div *ngIf="angForm.controls['confirmPassword'].errors.required">
confirmPassword is required.
</div>
</div>
<div class="form-group">
<button (click)="addUser(inputfirstname.value, inputlastname.value,inputEmail.value,inputPassword.value,confirmPassword.value)" [disabled]="angForm.pristine || angForm.invalid" class="btn btn-primary">Add</button>
</div>
</form>
</div>
Registration.component.js
import { Component, OnInit, NgModule } from '#angular/core';
import { FormGroup, FormBuilder, Validators } from '#angular/forms';
//import users class
import {UserService} from './../../user.service'
#Component({
selector: 'app-registration',
templateUrl: './registration.component.html',
styleUrls: ['./registration.component.css']
})
export class RegistrationComponent implements OnInit {
angForm: FormGroup;
constructor(private userservice: UserService, private fb: FormBuilder) {
this.createForm();
}
//user form
createForm() {
this.angForm = this.fb.group({
inputfirstname: ['', Validators.required ],
inputlastname: ['', Validators.required ],
inputEmail: ['', Validators.required ],
inputPassword: ['', Validators.required ],
confirmPassword: ['', Validators.required ]
});
}
addUser(inputfirstname, inputlastname, inputEmail, inputPassword, confirmPassword ) {
this.userservice.addUser(inputfirstname, inputlastname, inputEmail, inputPassword, confirmPassword);
}
ngOnInit() {
// //Create a new user object
// this.user = new user({
// firstname:"",lastname:"",email:"", password: { pwd: "" , confirm_pwd: ""}, terms:false})
}
}
user.service.ts
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { FormGroup, FormBuilder, Validators } from '#angular/forms';
#Injectable()
export class UserService {
constructor(private http: HttpClient) { }
addUser(inputfirstname, inputlastname, inputEmail, inputPassword, confirmPassword) {
const uri = 'http://localhost:4200/signup';
const obj = {
inputfirstname: inputfirstname,
inputlastname: inputlastname,
inputEmail: inputEmail,
inputPassword: inputPassword,
confirmPassword: confirmPassword
};
this.http.post(uri, obj)
.subscribe(res => console.log('Done'));
}
}
singup.js on server side
var express = require('express');
//var router = express.Router();
var router =express();
var registrationSchema = require('../models/Registration.js');
/* GET users listing. */
// router.get('/', function(req, res, next) {
// console.log(registrat);
// });
// Defined store route
router.route('/next').post (function(req,res){
var registerData = new registrationSchema(req.body);
registerData.save().then(item=>{
res.status(200).json({'registerData': 'data added successfully'});
})
.catch(err => {
res.status(400).send("unable to save to database");
});
})
// Defined get data(index or listing) route
router.route('/').get(function (req, res) {
console.log(req.body);
registrationSchema.find(function (err, data){
if(err){
console.log(err);
}
else {
res.json(data);
}
});
});
//registration
router.route('/signup').post (async function (req, res) {
//to add validation?
//create new user
var newUser = new registrationSchema(req.body);
console.log('req.body');
var isCreated = await registrationSchema.inputData(newUser).then(result =>{
if (result)
{
console.log(isCreated);
res.status(200).send({success:true,message:"User Created!"})
}
else
console.log(err);
})
})
//login
router.route('/login'), async function (req, res){
}
module.exports = router;
i would like to hear your idea. allready tested the form at root and changing paths. i recive same errors.
last try was to create a form using different way. and again nothing.
thank you for your time,
Best regards!
addUser(inputfirstname, inputlastname, inputEmail, inputPassword, confirmPassword) {
const uri = 'http://localhost:4200/signup';
uri belongs to the server! i mixed up the idea. need to be the server ip + port + callout router from server.
and the submision is wrong. had to restudy the http docs.

Resources