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);
}
Related
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)
})
I made a NodeJS server and an Angular 8 client to send and receive messages with socket.io. The server does receive the message but does not send/angular does not receive the message. Does this happen because I use localhost or did I do something wrong codewise?
NodeJS server:
let express = require('express');
let app = express();
let http = require('http');
let server = http.Server(app);
let socketIO = require('socket.io');
let io = socketIO(server);
const port = process.env.PORT || 3000;
io.on('connection', (socket) => {
console.log('user connected');
socket.on('new-message', (message) => {
console.log(message);
io.emit(message);
});
});
server.listen(port, () => {
console.log(`started on port: ${port}`);
});
Angular service:
import * as io from 'socket.io-client';
import { Observable } from 'rxjs/Observable';
import {Observer} from 'rxjs';
export class ChatService {
private url = 'http://localhost:3000';
private socket;
constructor() {
this.socket = io(this.url);
}
public sendMessage(message) {
this.socket.emit('new-message', message);
}
public getMessages = () => {
// return Observable.create((observer) => {
// console.log(observer);
// this.socket.on('new-message', (message) => {
// observer.next(message);
// });
// });
return new Observable((observer) => {
this.socket.on('new-message', (message) => {
observer.next(message);
observer.complete();
});
});
}
}
Angular component:
export class HomeComponent implements OnInit {
private message: string;
constructor(private chatService: ChatService) {
this.message = 'hello';
this.sendMessage();
}
ngOnInit(): void {
this.chatService.getMessages().subscribe((message: string) => {
console.log(message);
}, err => {
console.log(err);
});
}
sendMessage() {
this.chatService.sendMessage(this.message);
}
}
App.module.ts:
#NgModule({
declarations: [
AppComponent,
HomeComponent
], imports: [
], providers: [
ChatService
], entryComponents: []
})
export class AppModule {
}
In your server code you wrote io.emit(message); but emit function is called with two parameters - event name, and message to send.
Change it into io.emit('new-message', message); and it should work.
you need to change io.emit(message) to io.emit("message", { message: message }).
this code worked for me.
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
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 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>