i need to pass some data from angular to node.js server. this is my angular postlist component:
import { Component, OnInit } from '#angular/core';
import { HttpClient } from "#angular/common/http";
#Component({
selector: 'app-postlist',
templateUrl: './postlist.component.html',
styleUrls: ['./postlist.component.css']
})
export class PostlistComponent implements OnInit {
constructor(private http: HttpClient) { }
public data="test";
ngOnInit(): void {
this.http
.post("http://localhost:3000/api/book",this.data);
}
}
my node.js server:
const express=require('express');
var app = express();
app.post('/api/book', function(req, res, next){
var data = req.body.params;
console.log(data);
});
app.listen(3000);
i'm trying to console.log the data but nothing happens.
you are missing .subscribe in your call. Change your code to :-
ngOnInit(): void {
this.http
.post("http://localhost:3000/api/book",this.data).subscribe();
}
and in nodejs just print req.body
If you are planning on printing the payload this.data, take req.body instead of req.body.params.
And also check if you have any cors errors in console, that can also be blocking your data from reaching your web server.
in the server, you must change the format of your message to JSON like this
app.get('/api/GetFlux',function(req,resp){
let data = "hello"
resp.send(JSON.stringify(data));
})
at angular level
GetFlux():Observable<any[]>{
return this.http.get<any>(this.APIUrlNode+'/GetFlux');
}
this.service.GetFlux().subscribe(res =>{
this.fluxList = {
data:res
}
console.log("Data from node "+this.fluxList.data)
//,
}, err => {
console.log(" err = "+err)
})
Related
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);
}
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);
});
}
}
I am working for mean stack application. I am able to connect express api and angular component, but i want to pass parameters to the api service.
Please find the code below for clearer idea,
Component Code
constructor(private _dataService: DataService){
var parametervalue = "Monthly";
this._dataService.getexternalSourceDetailFiltered().subscribe((data) => {
this.source.load(data);
});}
DataService Code
import { Injectable } from '#angular/core';
import { Http } from '#angular/http';
import 'rxjs/add/operator/map';
#Injectable()
export class DataService {
result;
constructor(private _http: Http) { }
getStudents(){
return this._http.get('/external_sources').map(result =>
this.result = result.json().data);
}
getexternalSourceDetail(){
return this._http.get('/external_sources_details').map(result =>
this.result = result.json().data);
}
getexternalSourceDetailFiltered(){
return this._http.get('/external_sources_details').map(result =>
this.result = result.json().data);
}
}
Express API Code
router.get('/external_sources_details_filtered',(req,res) =>{
connection((db) => {
var intId = parseInt(0);
var query ={'frequency.Monthly':{$exists:true}};
var projection = {_id:0,sourceID:1,SourceName:1, Outstanding:1};
db.collection('external_sources').find(query).project(projection).
toArray().then((external_sources_details_filtered) => {
response.data = external_sources_details_filtered;
res.json(response);
})
})
})
How would i pass parametervalue from the component so that i can use it in express API to pass parameter to call mongodb using dynamic parameter
SOLUTION: Being totally new i searched around and found a solution:
i used URLSearchParams to set the parameter to pass through the express API.
Here is the the code for better understanding,
Component Code:
constructor(private _dataService: DataService){
var param = new URLSearchParams();
param.append('frequency','Monthly');
this._dataService.getexternalSourceDetailFiltered(param).subscribe((data) => {
this.source.load(data);
});
}
Data Service Code
getexternalSourceDetailFiltered(parameterValue:any ){
return this._http.get('/external_sources_details_filtered',
{
params:parameterValue}).map(result => this.result = result.json().data);
}
Express API js Code
router.get('/external_sources_details_filtered',(req,res) =>{
let parameterValue;
connection((db) => {
if(req.query.frequency != '')
{
parameterValue = String( 'frequency.'+ req.query.frequency);
}
else
{
parameterValue = String( 'frequency');
}
console.log(parameterValue);
var query = {[parameterValue] :{$exists:true}};
var projection = {_id:0,sourceID:1,SourceName:1, Outstanding:1};
db.collection('external_sources').find(query).project(projection).toArray().then((external_sources_details_filtered) => {
response.data = external_sources_details_filtered;
res.json(response);
})
})
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>
I am getting the following error when returning from a http service and attempting to push to response onto an array :
Cannot read property 'messages' of undefined
This is my chat.component.ts file :
import { Component, OnInit, OnDestroy } from '#angular/core';
import { ChatService } from './chat.service';
#Component({
selector: 'chat-component',
template: `
<div *ngIf="messages">
<div *ngFor="let message of messages">
{{message.text}}
</div>
</div>
<input [(ngModel)]="message" /><button (click)="sendMessage()">Send</button>
`,
providers: [ChatService]
})
export class ChatComponent implements OnInit, OnDestroy {
messages = [];
connection;
message;
loading;
constructor(private chatService: ChatService) { }
sendMessage() {
this.chatService.sendMessage(this.message);
this.message = '';
}
ngOnInit() {
this.chatService.initPlaylist().subscribe(tracks => {
tracks.forEach(function(item) {
this.messages.push({
message: item.trackID,
type: "new-message"
});
});
})
this.connection = this.chatService.getMessages().subscribe(message => {
this.messages.push(message);
})
}
ngOnDestroy() {
this.connection.unsubscribe();
}
}
This is my chat.service.ts
import { Injectable } from '#angular/core';
import { Http, Response } from '#angular/http';
import { Subject } from 'rxjs/Subject';
import { Observable } from 'rxjs/Rx';
import * as io from 'socket.io-client';
#Injectable()
export class ChatService {
private url = 'http://localhost:1337';
private socket;
constructor(private http: Http) {
}
sendMessage(message) {
this.socket.emit('add-message', message);
}
initPlaylist() {
return this.http.get(this.url + '/playlist')
.map(this.extratData)
.catch(this.handleError);
}
getMessages() {
let observable = new Observable(observer => {
this.socket = io(this.url);
this.socket.on('message', (data) => {
observer.next(data);
});
return () => {
this.socket.disconnect();
};
})
return observable;
}
private extratData(res: Response) {
let body = res.json();
return body || {};
}
private handleError(error: Response | any) {
// In a real world app, we might use a remote logging infrastructure
let errMsg: string;
if (error instanceof Response) {
const body = error.json() || '';
const err = body.error || JSON.stringify(body);
errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
} else {
errMsg = error.message ? error.message : error.toString();
}
console.error(errMsg);
return Observable.throw(errMsg);
}
}
I currently have a form on the front end, in which users can add a message, this is then pushed onto this.messages and through socket.io sent out to all connected sockets.
What I am now doing is storing messages in a mongodb via an express app using mongoose.
On page load, I would like to retrieve these messages from the document store, and push them onto this.messages - so the view is updated with previous messages, then socket.io should take over on new messages, adding them to the array.
As this is an initial call, once on load, I am not using socket.io to grab these, instead I have an api route setup through express, returning json that looks as follows :
[
{
"_id": "58109b3e868f7a1dc8346105",
"trackID": "This is my message...",
"__v": 0,
"status": 0,
"meta": {
"played": null,
"requested": "2016-10-26T12:02:06.979Z"
}
}
]
However when I get to this section of code within chat.component.ts, everything breaks down with the previously mentioned error..
this.chatService.initPlaylist().subscribe(tracks => {
tracks.forEach(function(item) {
this.messages.push({
message: item.trackID,
type: "new-message"
});
});
})
I using Angular 2, Socket.io, ExpressJS and MongoDB.
don't use function () use instead () => (arrow function) for this.... to keep pointing to the local class instance
tracks.forEach((item) => {
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions