Angular 6 + NodeJS + MongoDB - node.js

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.

Related

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)

react login register form sends empty data

I have a backend setup with node and express and frontend is React + Redux
The backend works well. I tested it all with insomina and i can successfully register a user and login.
On the front end side, everything looks ok except for the fact that when i try to login or register a user, it tells me that the input fields are required, which means that it sends an empty object to my backend. I also have a message in the console saying that componentWillReceiveProps(nextProps) is depricated and suggests using getDerivedStateFromProps instead. The issue is that i am new to React and have no idea how to convert that block. Can someone tell me? Is that even why the form sends an empty object?
EDIT: Added github repo for complete code
https://github.com/onidemon/wh-evcharge
Register.js is below, both login and Register have a componentWillReceiveProps block which i think might be causing the issue. Not sure how to convert them to getDerivedStateFromProps if that is even the cause of the problem.
import React, { Component } from "react";
import { Link, withRouter } from "react-router-dom";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { registerUser } from "../../actions/authActions";
import classnames from "classnames";
class Register extends Component {
constructor() {
super();
this.state = {
name: "",
email: "",
password: "",
password2: "",
errors: {}
};
}
componentDidMount() {
// If logged in and user navigates to Register page, should redirect them to dashboard
if (this.props.auth.isAuthenticated) {
this.props.history.push("/dashboard");
}
}
componentWillReceiveProps(nextProps) {
if (nextProps.errors) {
this.setState({
errors: nextProps.errors
});
}
}
onChange = e => {
this.setState({ [e.target.id]: e.target.value });
};
onSubmit = e => {
e.preventDefault();
const newUser = {
name: this.state.name,
email: this.state.email,
password: this.state.password,
password2: this.state.password2
};
this.props.registerUser(newUser, this.props.history);
};
render() {
const { errors } = this.state;
return (
<div className="container">
<div className="row">
<div className="col s8 offset-s2">
<Link to="/" className="btn-flat waves-effect">
<i className="material-icons left">keyboard_backspace</i> Back to
home
</Link>
<div className="col s12" style={{ paddingLeft: "11.250px" }}>
<h4>
<b>Register</b> below
</h4>
<p className="grey-text text-darken-1">
Already have an account? <Link to="/login">Log in</Link>
</p>
</div>
<form noValidate onSubmit={this.onSubmit}>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.name}
error={errors.name}
id="name"
type="text"
className={classnames("", {
invalid: errors.name
})}
/>
<label htmlFor="name">Name</label>
<span className="red-text">{errors.name}</span>
</div>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.email}
error={errors.email}
id="email"
type="email"
className={classnames("", {
invalid: errors.email
})}
/>
<label htmlFor="email">Email</label>
<span className="red-text">{errors.email}</span>
</div>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.password}
error={errors.password}
id="password"
type="password"
className={classnames("", {
invalid: errors.password
})}
/>
<label htmlFor="password">Password</label>
<span className="red-text">{errors.password}</span>
</div>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.password2}
error={errors.password2}
id="password2"
type="password"
className={classnames("", {
invalid: errors.password2
})}
/>
<label htmlFor="password2">Confirm Password</label>
<span className="red-text">{errors.password2}</span>
</div>
<div className="col s12" style={{ paddingLeft: "11.250px" }}>
<button
style={{
width: "150px",
borderRadius: "3px",
letterSpacing: "1.5px",
marginTop: "1rem"
}}
type="submit"
className="btn btn-large waves-effect waves-light hoverable blue accent-3"
>
Sign up
</button>
</div>
</form>
</div>
</div>
</div>
);
}
}
Register.propTypes = {
registerUser: PropTypes.func.isRequired,
auth: PropTypes.object.isRequired,
errors: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
auth: state.auth,
errors: state.errors
});
export default connect(
mapStateToProps,
{ registerUser }
)(withRouter(Register));
Login.js is below
import React, { Component } from "react";
import { Link } from "react-router-dom";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { loginUser } from "../../actions/authActions";
import classnames from "classnames";
class Login extends Component {
constructor() {
super();
this.state = {
email: "",
password: "",
errors: {}
};
}
componentDidMount() {
// If logged in and user navigates to Login page, should redirect them to dashboard
if (this.props.auth.isAuthenticated) {
this.props.history.push("/dashboard");
}
}
componentWillReceiveProps(nextProps) {
if (nextProps.auth.isAuthenticated) {
this.props.history.push("/dashboard");
}
if (nextProps.errors) {
this.setState({
errors: nextProps.errors
});
}
}
onChange = e => {
this.setState({ [e.target.id]: e.target.value });
};
onSubmit = e => {
e.preventDefault();
const userData = {
email: this.state.email,
password: this.state.password
};
this.props.loginUser(userData);
};
render() {
const { errors } = this.state;
return (
<div className="container">
<div style={{ marginTop: "4rem" }} className="row">
<div className="col s8 offset-s2">
<Link to="/" className="btn-flat waves-effect">
<i className="material-icons left">keyboard_backspace</i> Back to
home
</Link>
<div className="col s12" style={{ paddingLeft: "11.250px" }}>
<h4>
<b>Login</b> below
</h4>
<p className="grey-text text-darken-1">
Don't have an account? <Link to="/register">Register</Link>
</p>
</div>
<form noValidate onSubmit={this.onSubmit}>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.email}
error={errors.email}
id="email"
type="email"
className={classnames("", {
invalid: errors.email || errors.emailnotfound
})}
/>
<label htmlFor="email">Email</label>
<span className="red-text">
{errors.email}
{errors.emailnotfound}
</span>
</div>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.password}
error={errors.password}
id="password"
type="password"
className={classnames("", {
invalid: errors.password || errors.passwordincorrect
})}
/>
<label htmlFor="password">Password</label>
<span className="red-text">
{errors.password}
{errors.passwordincorrect}
</span>
</div>
<div className="col s12" style={{ paddingLeft: "11.250px" }}>
<button
style={{
width: "150px",
borderRadius: "3px",
letterSpacing: "1.5px",
marginTop: "1rem"
}}
type="submit"
className="btn btn-large waves-effect waves-light hoverable blue accent-3"
>
Login
</button>
</div>
</form>
</div>
</div>
</div>
);
}
}
Login.propTypes = {
loginUser: PropTypes.func.isRequired,
auth: PropTypes.object.isRequired,
errors: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
auth: state.auth,
errors: state.errors
});
export default connect(
mapStateToProps,
{ loginUser }
)(Login);
EDIT: Added AuthActions.js
import axios from "axios";
import setAuthToken from "../utils/setAuthToken";
import jwt_decode from "jwt-decode";
import { GET_ERRORS, SET_CURRENT_USER, USER_LOADING } from "./types";
// Register User
export const registerUser = (userData, history) => dispatch => {
axios
.post("/api/users/register", userData)
.then(res => history.push("/login"))
.catch(err =>
dispatch({
type: GET_ERRORS,
payload: err.response.data
})
);
};
// Login - get user token
export const loginUser = userData => dispatch => {
axios
.post("/api/users/login", userData)
.then(res => {
// Save to localStorage
// Set token to localStorage
const { token } = res.data;
localStorage.setItem("jwtToken", token);
// Set token to Auth header
setAuthToken(token);
// Decode token to get user data
const decoded = jwt_decode(token);
// Set current user
dispatch(setCurrentUser(decoded));
})
.catch(err =>
dispatch({
type: GET_ERRORS,
payload: err.response.data
})
);
};
// Set logged in user
export const setCurrentUser = decoded => {
return {
type: SET_CURRENT_USER,
payload: decoded
};
};
// User loading
export const setUserLoading = () => {
return {
type: USER_LOADING
};
};
// Log user out
export const logoutUser = () => dispatch => {
// Remove token from local storage
localStorage.removeItem("jwtToken");
// Remove auth header for future requests
setAuthToken(false);
// Set current user to empty object {} which will set isAuthenticated to false
dispatch(setCurrentUser({}));
};
I looked on your github project.
If I am not mistaken I haven't seen you using in your server the bodyparser.json() function. You only use the bodyParser.urlencoded(), which convert url parameters into processable objects.
Add as well bodyParser.json(), then you would get the incoming data from the body of the request as well. Then you should have it I believe.

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.

How upload image in angular 7 from backend

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')

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);

Resources