Angular 7 Form in production - node.js

I am trying to put into operation a form that sends me data to the mail with nodemailer
in localhost: 3000 it works well but when loading my project on the server with the community I can not get this code to work
an application in the root of the project called nodeMensajeria / src / node modules, app.js and configMensaje.js
mira la raiz de mi proyecto
app.js
const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const configMensaje = require('./configMensaje');
const app = express();
app.use(bodyParser.json());
app.use(cors())
app.post('/formulario', (req, res) => {
configMensaje(req.body);
res.status(200).send();
})
app.listen(3000, () => {
console.log('Servidor corriendo')
});
configMensaje.js
const nodemailer = require('nodemailer');
module.exports = (formulario) => {
var transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'correoorigen',
pass: 'contraseña'
}
});
const mailOptions = {
from: `"${formulario.nombre} 👻" <${formulario.email}>`,
to: 'correodestino', //
subject: formulario.asunto,
html: `
<strong>Nombre:</strong> ${formulario.nombre} <br/>
<strong>Asunto:</strong> ${formulario.asunto} <br/>
<strong>E-mail:</strong> ${formulario.email} <br/>
<strong>Número de contacto:</strong> ${formulario.contacto} <br/>
<strong>Mensaje:</strong> ${formulario.mensaje}
`
};
transporter.sendMail(mailOptions, function (err, info) {
if (err)
console.log(err)
else
console.log(info);
});
}
the service message.service.ts
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http'
#Injectable({
providedIn: 'root'
})
export class MessageService {
constructor(private _http: HttpClient) { }
sendMessage(body) {
return this._http.post('http://107.180.59.131:3000/formulario', body);
}
}
I am using the ip of my domain
app.component.ts
import { Component, OnInit } from '#angular/core';
import { MessageService } from '../services/message.service';
import swal from 'sweetalert';
import { VirtualTimeScheduler } from 'rxjs';
#Component({
selector: 'app-form',
templateUrl: './form.component.html',
styleUrls: ['./form.component.scss']
})
export class FormComponent implements OnInit {
constructor(public _MessageService: MessageService) { }
contactForm(form) {
this._MessageService.sendMessage(form).subscribe(() => {
swal("Formulario de contacto", "Mensaje enviado correctamente", 'success');
});
}
ngOnInit() {
}
}
It shows me that the app is executed
but when sending the form in production it shows me the following error
Failed to load resource: net::ERR_CONNECTION_TIMED_OUT
main.5cb5f6b8477568c35bd7.js:1 ERROR e {headers: t, status: 0, statusText: "Unknown Error", url: "http://107.180.59.131:3000/formulario", ok: false, …}
look at the error

you have to deploy the express api into your server, this link could help you https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs/deployment
you are using the developement mode to work in the production server and your firewall its blocking the port 3000, when you deploy the api, you've to send the post to http://YOUR_IP/endpoint or http://api.IP/endpoint

Related

Angular: Error while fetching data from Node API?

I am trying to fetch json data from my Nodejs API using URL - localhost:3000/articles/publicationData which is running successfully in Postman app but don't know why is giving error with same url in angular app, but in Angular app it is giving an error -
HttpErrorResponse {headers: HttpHeaders, status: 404, statusText: "Not Found", url: "http://localhost:3000/articles/publicationData", ok: false, …}
error: "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<title>Error</title>\n</head>\n<body>\n<pre>Cannot GET /articles/publicationData</pre>\n</body>\n</html>\n"
headers: HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, lazyInit: ƒ}
message: "Http failure response for http://localhost:3000/articles/publicationData: 404 Not Found"
name: "HttpErrorResponse"
ok: false
status: 404
statusText: "Not Found"
url: "http://localhost:3000/articles/publicationData"
My app-service.ts file is -
import { Injectable } from '#angular/core';
import { HttpClient} from '#angular/common/http';
import { AppSetting } from './appsetting'
#Injectable({
providedIn: 'root'
})
export class AppServiceService {
private SERVERURL = AppSetting.API;
constructor(private http: HttpClient) { }
login(user){
console.log(user);
return this.http.post<any>(this.SERVERURL+"users",user);
}
getPublication(){
let url = "http://localhost:3000/articles/publicationData";
return this.http.get(url);
}
}
My app.component.ts file
import { Component, OnInit } from '#angular/core';
import { DatepickerModule } from 'ng2-datepicker';
import { HttpClient } from '#angular/common/http';
import { Router } from '#angular/router';
import { DatepickerOptions } from 'ng2-datepicker';
import { AppServiceService } from './../app-service.service';
import { Subscriber } from 'rxjs';
#Component({
selector: 'app-main',
templateUrl: './main.component.html',
styleUrls: ['./main.component.css']
})
export class MainComponent implements OnInit {
constructor(private http: HttpClient,private auth : AppServiceService, private _router: Router) {
this.auth.getPublication().subscribe(data => {
console.warn(data);
})
}
ngOnInit(): void {
$("#menu-toggle").click(function(e) {
e.preventDefault();
$("#wrapper").toggleClass("toggled");
});
}
}
Controller.js
var db = require("../db.js");
var ObjectId = require('mongodb').ObjectID;
var mysql = require('mysql');
var connection = mysql.createPool({
host: 'localhost',
user: 'root',
password: 'pass',
database: 'name'
});
var publicationData = (req, res) => {
var sql = `select pub_master.PubId, pub_master.Title,
pub_master.MastHead, pub_master.Circulation, pub_master.WebSite,
pub_master.Issn_Num, pub_master.Place, picklist.Name as city
from pub_master
join picklist on picklist.id = pub_master.Place
and picklist.id <> 0`;
connection.query(sql,[], function (error, results, fields) {
if (error) {
res.send({
"code":400,
"failed":"error ocurred"
})
}else{
if(results.length >0){
res.send({
"code":200,
result : results
});
}
else{
res.send({
"code":204,
"success":"Email and password does not match"
});
}
}
});
}
module.exports = {
publicationData: publicationData
}
Publication route
var express = require("express");
var articlescontroller = require("../controller/articlesController")
var articlesrouter = express.Router();
articlesrouter.route('/publicationData')
.post(articlescontroller.publicationData);
app.js
var express = require("express");
const serverless = require('serverless-http');
var moviesrouter = require("./routes/movierouter");
var articlesrouter = require("./routes/articlesrouter");
// var mailarticlerouter = require('./routes/mailarticlerouter');
var bodyParser = require("body-parser");
var mongoos = require("mongoose");
/*****************MYSQL CONNECTION*********************/
var mysql = require('mysql');
var connection = mysql.createPool({
host : '',
user : '',
password : '',
database : ''
});
/************************************* */
mongoos.set("debug", (collectionName, method, query, doc) => {
console.log(JSON.stringify(query));
});
mongoos.Promise = Promise;
var db = mongoos.connect("mongodb+srv://aamadmin:Rix2Jag8#irmpl-zame7.mongodb.net/impact?retryWrites=true&w=majority",{useUnifiedTopology: true,useNewUrlParser:true});
console.log("connected to mongodb");
var app = express();
var cors = require('cors');
const userrouter = require("./routes/userrouter");
app.use(cors());
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
app.use(bodyParser.json());
var server = app.listen(3000,()=>{
console.log("server is running on port 3000");
});
server.timeout = 600000;
module.exports.handler = serverless(app);
app.use('/articles',articlesrouter);
From your Postman screen, you need to send a POST request to localhost:3000/articles/publicationData, not a GET request. You have the 404 error with your code and when trying to access localhost:3000/articles/publicationData in browser because you're sending GET requests.
In your Angular code, change from :
getPublication(){
let url = "http://localhost:3000/articles/publicationData";
return this.http.get(url);
}
to :
getPublication(){
let url = "http://localhost:3000/articles/publicationData";
return this.http.post(url, {});
}

Angular HTTP GET not hitting Express Route

My Angular HTTP GET Request indside clearNotifications() in notification.service.ts not hitting Express Route routes/notifications.js. I am calling clearNotifications() from a component called app.component.ts. I am using Angular 7+
routes/notifications.js
const router = require('express').Router();
//Additional modules
// const db = require('../config/database');
// const notificationModel = require('../models/notifications');
//Test connection
// db.authenticate().then(() => {
// console.log('Connection has been established successfully.');
// }).catch(err => {
// console.error('Unable to connect to the database:', err);
// });
//Clear all notifications
router.get('/clear', (req, res, next) => {
console.log('clear');
// notificationModel.destroy({});
});
module.exports = router;
notification.service.ts
import { Injectable } from '#angular/core';
import * as io from 'socket.io-client';
import { Observable } from 'rxjs';
import { HttpClient } from '#angular/common/http';
#Injectable({
providedIn: 'root'
})
export class NotificationService {
uri = 'http://localhost:5000';
private socket = io(this.uri);
constructor(private http: HttpClient) { }
getNotification() {
let observable = new Observable<{ string: String, number: String }>(observer => {
this.socket.on('notification', (data) => {
observer.next(data);
});
// return () => { this.socket.disconnect(); }
})
return observable;
}
clearNotifications() {
return this.http.get(`${this.uri}/notifications/clear`);
}
}
app.component.ts
import { Component } from '#angular/core';
import { NotificationService } from './notification.service';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [NotificationService]
})
export class AppComponent {
title = 'client';
string: String;
number: String;
notificationArray: Array<{ string: String, number: String }> = [];
constructor(private notificationService: NotificationService) {
this.notificationService.getNotification().subscribe(data => {
this.notificationArray.push(data);
});
}
clearNotifications() {
this.notificationArray = [];
this.notificationService.clearNotifications();
}
}
You should be doing this: Check the basic routing on express
var express = require('express');
var app = express();
app.get('/clear', (req, res) => {
console.log('clear');
res.send(success);
// notificationModel.destroy({});
});
Also make sure to subscribe to the service method from your component. If you do not subscribe the observables won't execute.
Where are you calling clearNotifications from?
subscribe to clearNotifications in component and this will work:
this.notificationService.clearNotifications().subscribe( (data) => { ..})
As a publisher, you create an Observable instance that defines a subscriber function. This is the function that is executed when a consumer calls the subscribe() method. The subscriber function defines how to obtain or generate values or messages to be published
In angular, http request returns observable, so you need to subscribe. If there aren't any subscriber to the observable, it wont be executed. Try
clearNotifications() {
return this.http.get(`${this.uri}/notifications/clear`)
.subscribe(data => //your callback function,
error => // your error handler,
complete => // any after completion task);
}

push notification with angular and nodejs

I have create push notification with angular and nodejs ..when I valid article i will send push notification to user will create article ... User1 create article and when admin valid this article user1 receive notification ... this is my code in general for receive notification but where is modification in my code for receive notification only for user1 .
code service angular:
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
const SERVER_URL = 'http://localhost:3000/subscription';
#Injectable()
export class PushNotificationService {
constructor(private http: HttpClient) {}
public sendSubscriptionToTheServer(subscription: PushSubscription) {
return this.http.post(SERVER_URL, subscription);
}
}
code component:
import { Component, OnInit } from '#angular/core';
import { SwPush } from '#angular/service-worker';
import { PushNotificationService } from '../../services/push-notification.service';
const VAPID_PUBLIC = "BJPrg7jbhWkWZn5mhg0Wti8031cHjsLGyN1G4pmfeippmEsXHo53wnRiqqjApVkA1KQyIz0IYK4ln0ie7RLrsiI";
const PRIVATE = "D1njq6Y7ny2QexJ-JZXbUpufCkfIywLSMvO6s-iSNoQ";
#Component({
selector: 'app-test-component',
templateUrl: './test-component.component.html',
styleUrls: ['./test-component.component.scss']
})
export class TestComponentComponent implements OnInit {
constructor(public swPush: SwPush, public pushService: PushNotificationService) {
}
test(){
if (this.swPush.isEnabled) {
this.swPush
.requestSubscription({
serverPublicKey: VAPID_PUBLIC
})
.then(subscription => {
this.pushService.sendSubscriptionToTheServer(subscription).subscribe();
})
.catch(console.error);
}
}
ngOnInit() {
}
}
code nodejs:
const express = require('express');
const webpush = require('web-push');
const cors = require('cors');
const bodyParser = require('body-parser');
const PUBLIC_VAPID = 'BJPrg7jbhWkWZn5mhg0Wti8031cHjsLGyN1G4pmfeippmEsXHo53wnRiqqjApVkA1KQyIz0IYK4ln0ie7RLrsiI';
const PRIVATE_VAPID = 'D1njq6Y7ny2QexJ-JZXbUpufCkfIywLSMvO6s-iSNoQ';
const fakeDatabase = [];
const app = express();
app.use(cors());
app.use(bodyParser.json());
webpush.setVapidDetails('mailto:mailto#gmail.com', PUBLIC_VAPID, PRIVATE_VAPID);
app.post('/subscription', (req, res) => {
const subscription = req.body;
fakeDatabase.push(subscription);
const notificationPayload = {
notification: {
title: 'New Notification',
body: 'This is the body of the notification',
icon: 'assets/icons/icon-512x512.png'
}
};
const promises = [];
fakeDatabase.forEach(subscription => {
promises.push(webpush.sendNotification(subscription, JSON.stringify(notificationPayload)));
});
fakeDatabase.length =0
Promise.all(promises).then(() => res.sendStatus(200));
});
app.listen(3000, () => {
console.log('Server started on port 3000');
});
help me and thank you for advanced

How to receive data from client using socket.io events inside express controller?

I am using Express framework with TypeScript:
I want to get client location at login using Socket IO, so on the client side, i made an emit event on login page. On the server side i tried to integrate a socket event into the login controller, which is placed before the response is sent back to the client, but the event from the server fires up just after i'm already signed in and clicked on sign out button which leads me to login page again (this is the moment when i receive the location message on server side from console.log(data)).
This is how the authentication controller file (auth.controller.ts) looks like:
import { io } from '../server/https';
....
..
public authenticate(req: Request, res: Response) {
if(req.body.email && req.body.password) {
....
..
io.on('connection', (socket: SocketIO.Socket) => {
console.log('New Socket Connected!');
socket.on('client-location', (data) => {
console.log(data);
});
socket.on('disconnect', (reason) => {
console.log(reason);
});
});
res.status(200).json({
resType: 'success',
token: 'Bearer ' + token,
userId: user.id,
message: 'Authenticated.',
loginNumber: result.session.length
});
};
....
..
}
The { io } import in the auth.controller.ts is the exported io constant from https.ts file.
Below is the https.ts file:
import socketIO from 'socket.io';
import HTTPS from 'https';
import app from '../app/index';
....
..
const options = {
cert: fs.readFileSync(path.resolve('../../../certificates/ca.crt')),
key: fs.readFileSync(path.resolve('../../../certificates/ca.key'))
}
export const server = HTTPS.createServer(options, app)
.listen(process.env.HTTP_SERVER_PORT, () => {
console.log(`Platform Server is running from
${process.env.HTTP_SERVER_HOST}, port: ${process.env.HTTP_SERVER_PORT}`);
});
export const io = socketIO.listen(server);
Something is not synchronized and i don't get it.
The client side is wrote in Angular 6 and the component from where the event is emited is below:
import { Component, OnInit } from '#angular/core';
import { LoginService } from '../../services/login.service';
import { Router } from '#angular/router';
import * as io from 'socket.io-client';
import { env } from '../../../../../environments/environment';
#Component({
selector: 'login-form',
templateUrl: './login-form.component.html',
styleUrls: ['./login-form.component.css']
})
export class LoginFormComponent implements OnInit {
public positionOptions = {
enableHighAccuracy: true,
maximumAge: 0
};
public LoginFormModel: any = {};
private URL = `${env.WS_SERVER_URL}:${env.HTTP_SERVER_PORT}`;
private socket;
constructor(private loginController: LoginService,
private router: Router) {
this.socket = io(this.URL);
}
ngOnInit() {}
public emitLocation() {
navigator.geolocation.getCurrentPosition(position => {
const { latitude: lat, longitude: lng } = position.coords;
console.log({ lat, lng });
this.socket.emit('client-location', { lat, lng });
},
err => {
console.log(err);
}, this.positionOptions);
}
loginEvent() {
this.loginController.login(this.LoginFormModel.email.value,
this.LoginFormModel.password.value)
.subscribe(
result => {
this.loginController.createSession('token', result.token);
this.emitLocation();
this.router.navigate(['user/profile']);
},
err => {
console.log(err);
});
}
}

How to pass form data from angular to nodejs

I am new to Angular5. I need to pass user details from angular to nodejs.
app.component.ts:
import { Component } from '#angular/core';
import { FormBuilder, FormGroup, Validators, FormControl, FormArray } from
'#angular/forms';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(private http:Http) { }
onSubmit(registerForm) {
console.log(registerForm.value);
let url = 'http://localhost:8080/signup';
this.http.post(url, {registerForm(registerForm)}).subscribe(res =>
console.log(res.json()));
}
}
Now I need to pass those data to nodejs routes to proceed further.
Node js routing file:
module.exports = function(app, passport) {
app.post('/signup', passport.authenticate('local-signup', {
successRedirect : '/',
failureRedirect : '/',
failureFlash : true
}));
};
Now am getting the following error: Uncaught Error: Can't resolve all parameters for AppComponent: (?).
Call Your function from the component.html file it will trigger the function which will be in your component.ts file.
From this function call service which contains the function which will be requesting your node API
addData() {
this.adminService.addCountry(this.form.value).subscribe(
res => {
var response = res.json();
this.flashMessagesService.show(response.message, {
cssClass: "alert-success",
timeout: 2000
});
},
error => {
if (error.status == 401) {
localStorage.removeItem("currentUser");
this.router.navigate(["/"]);
} else {
this.flashMessagesService.show(error.json().error, {
cssClass: "alert-danger",
timeout: 2000
});
}
}
);
}
Create admin service to call your HTTP URL which is running on node
Service
addCountry(formData) {
console.log(formData);
var authToken = this.getAuthToken();
if (authToken != "") {
var headers = this.getHeaders();
headers.append("Authorization", authToken);
return this.http
.post(
`http://localhost:3000/addData`,
this.formData(formData),
{ headers: headers }
)
.map((response: Response) => {
return response;
});
}
}
You can use service in angular to send data to nodeJs. Please refer the tutorials of Angular from Codecraft. Please have a look at https://codecraft.tv/courses/angular/http/core-http-api/
For now you need to send some registration form data. So
1. import http module to AppModule
2. Refer to the documentation above
3. You can pass data to nodejs using a POST method of http
I think you should look on Observable.
https://angular.io/guide/observables
On logic you should create server with Observable request to your NodeJs (express) app. Then you can add to your component function with subscribe.
Some code:
Create authentication service
ng generate service authentication
Create user service for store user data (or you can only store it in other components)
ng generate service user
On authentication.service.ts create authenticate method
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import { UserService } from '../user/user.service';
import { Router } from '#angular/router';`
#Injectable()
export class AuthenticationService {
token: string;
constructor(private router: Router, private httpClient: HttpClient,
public userService: UserService) {
const currentUser = JSON.parse(localStorage.getItem('currentUser'));
this.token = currentUser && currentUser.token;
}
getToken(email: string, password: string): Observable<User> {
return this.httpClient.post<User>(apiRoutes.authentication,
{userEmail: email, userPassword: password});
}
authenticate(email: string, password: string) {
this.getToken(email, password).subscribe(response => {
if (response.userToken.length > 0) {
this.userService.user.userEmail = response.userEmail;
this.userService.user.userToken = response.userToken;
this.userService.user._id = response._id;
this.userService.user.isUserAuthenticated = true;
localStorage.setItem('currentUser', JSON.stringify({token: response.userToken}));
this.router.navigate(['/']);
// TODO: Need some error logic
} else {
return false;
}
});
}
Now you can add to your form in template
<form (ngSubmit)="this.authenticationService.authenticate(userEmail, password)">
...
</form>

Resources