In my angular app, I send a post request to node API with JSON data object, but it doesn't work as intended. In the request payload, the JSON data object is not shown.
When i send a JSON string by using JSON.stringify(auth) it's shown in the request payload but can't be parsed by the json body-parser at the node backend. Requests body is empty. Give me a solution to this problem.
My code
import { Injectable } from "#angular/core";
import { AuthData } from "../modules/AuthData";
import {
HttpClient,
HttpParams,
HTTP_INTERCEPTORS,
HttpInterceptor,
HttpHeaders
} from "#angular/common/http";
#Injectable({
providedIn: "root"
})
export class AuthService {
private url = "http://localhost:3000";
private httpOptions = {
headers: new HttpHeaders({
"Content-Type": "application/json",
Authorization: "my-auth-token",
"Request-Method": "post"
})
};
constructor(private http: HttpClient) {}
login(email: string, password: string) {
const authData = { email: email, password: password };
console.log(authData);
this.http
.post(this.url + "/api/user/login", authData)
.subscribe(response => {
console.log(response);
});
}
}
My backend code
const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const mongoose = require("mongoose");
const cors = require('cors');
const userRoute = require("./routes/user");
const app = express();
mongoose
.connect('mongodb://localhost:27017/tryondb', {
useNewUrlParser: true
})
.then(() => {
console.log("connected to the database");
})
.catch(() => {
console.log("connection failed");
})
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:false}));
//var jsonParser = bodyParser.json();
//var urlencodedParser = bodyParser.urlencoded({ extended: false });
//app.use(cors);
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader(
"Access-Control-Allow-Header",
"Origin, X-Requested-with, Content-Type, Accept"
);
res.setHeader(
"Access-Control-Allow-Methods",
"GET, POST, PATCH, DELETE, OPTIONS"
);
console.log("rrr");
next();
})
app.post("/api/user/login",(req,res,next)=>{
console.log(req);
});
app.use("/api/user", userRoute);
console.log("aaa");
module.exports = app;
you are creating httpoptions but you are not passing them correctly: try
login(email: string, password: string) {
const authData = { email: email, password: password };
console.log(authData);
this.http
.post(this.url + "/api/user/login", authData, httpOptions)
.subscribe(response => {
console.log(response);
});
}
Related
i am trying to get the response from passport.js from node js to react js,i am sending the access and refresh token once user logi's in with google but i am not sure how to take response from node to react
React Code
const googleAuth = async () => {
window
.open('http://localhost:4000/oauth/google', '_self')
};
Node Code
I can able to verify the user and generate access and refresh token but i am not sure how to get these response in react
passport.use(
new GoogleStrategy(
{
clientID: GOOGLE_CLIENT_ID,
clientSecret: GOOGLE_CLIENT_SECRET,
callbackURL: "/google/callback",
},
async function (accessToken, res, refreshToken, profile, done) {
done(null, profile);
const enteredemail = profile.emails.map((a) => a.value);
const sftoken = await getSfToken();
var configHeaders = {
method: "get",
headers: {
Authorization: `Bearer ${sftoken}`,
"Content-Type": `application/json`,
},
};
const emailcheck = await axios.get(
`URL`,
configHeaders
);
if (emailcheck.data.success === true) {
const logintoken = await axios.get(
"URL"
);
const acctok = logintoken?.data?.access_token;
const url = `URL`;
const res = await axios.post(
url,
{},
{
headers: {
Authorization: `Bearer ${acctok}`,
},
}
);
const refreshTokenURL = `URL`;
const refresTok = await axios.get(refreshTokenURL, {
headers: {
Authorization: `Bearer ${acctok}`,
},
});
console.log("refreshToken", refresTok);
} else {
return null
}
}
)
);
passport.serializeUser((user, done) => {
done(null, user);
});
passport.deserializeUser((user, done) => {
done(null, user);
});
I have a webpack-dev-server config like
const path = require('path')
const CircularJSON = require('circular-json') //just to allow me to log circular references
module.exports = {
...
devServer: {
before(app) {
app.all('/my/route', (req, res) => {
console.log(CircularJSON.stringify(req))//req.query & req.params are empty {}
// I wanna have access to sent payload from Axios here, eg:
const result = {
foo1: req.query.bar1,
foo2: req.query.bar2
}
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify(result));
});
}
}
}
The equivalent axios call is like
axios.post('/my/route', {bar1: 'x', bar2: 'y'}).then(...) => {...})
I'm able to hit the route because I got the console.log(CircularJSON.stringify(req)) output, but the req.query & req.params are empty. I suspect it is due to the fact that I was sending JSON data, but even with extra axios config {headers: { 'Content-Type': 'application/json' }} I couldn't get the data I wanna send.
Any idea ?
the solution was to use 'body-parser'
const path = require('path')
const CircularJSON = require('circular-json') //just to allow me to log circular references
const bodyParser = require('body-parser')
module.exports = {
...
devServer: {
before(app) {
// use bodyParser for axios request
app.use(bodyParser.urlencoded({ extended: true }))
app.use(bodyParser.json())
app.all('/my/route', (req, res) => {
console.log(CircularJSON.stringify(req))//req.query & req.params are empty {}
// access them on req.body:
const result = {
foo1: req.body.bar1,
foo2: req.body.bar2
}
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify(result));
});
}
}
}
I'm trying to create a web application using Angular and Node for study, but my PUT request isn't working even though my GET requests work. It seems like Node is ignoring the requests and I can't find why. In my app I try to edit the name of a user when clicking a button and I can see that the request works until it gets to the http client in users-service.service.ts.
users.component.html
<router-outlet></router-outlet>
<h3>Usuários</h3>
<table>
<tr><td>Nome</td></tr>
<tr *ngFor="let user of users"><td>{{user.first_name}}</td><td><button (click)="showUserInfo($event, user)">Editar</button></td></tr>
</table>
<br/><br/>
<div>
<label>First Name: </label><input type="text" value="{{user.first_name}}" (input)="user.first_name = $event.target.value">
<label>Last Name: </label><input type="text" value="{{user.last_name}}" (input)="user.last_name= $event.target.value">
<button (click)="updateUser()">Salvar</button>
</div>
<br/><br/>
<button (click)="loadAllUsers()">Reload</button>
users.component.ts
import { HttpClient, HttpClientModule } from '#angular/common/http';
import { UsersService, User } from './../users-service.service';
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-users',
providers: [UsersService, HttpClient, HttpClientModule],
templateUrl: './users.component.html',
styleUrls: ['./users.component.sass']
})
export class UsersComponent implements OnInit {
private users: User[];
private user: User = {first_name: '', last_name: '', id: null};
constructor(private service: UsersService) {
this.loadAllUsers();
}
ngOnInit() {}
showUserInfo(event, u : User) {
this.user = u;
}
loadAllUsers() {
this.service.getAllUsers().subscribe(valor => { this.users = valor as User[] });
}
updateUser() {
console.log(this.user);
this.service.updateUser(this.user);
}
}
users-service.service.ts
import { HttpClient, HttpClientModule, HttpHeaders } from '#angular/common/http';
import { Injectable } from '#angular/core';
import { Observable } from 'rxjs';
export interface User{
first_name: string,
last_name: string,
id: number
}
#Injectable()
export class UsersService{
constructor(private http: HttpClient) { }
getAllUsers(): Observable<User[]>{
return this.http.get<User[]>("http://localhost:4600/api/users");
}
updateUser(user: User): Observable<void>{
console.log('Updating: ' + user);
console.log("http://localhost:4600/api/users/" + user.id);
return this.http.put<void>("http://localhost:4600/api/users/" + user.id, user);
}
}
server.js
const express = require('express');
app = new express();
const morgan = require('morgan');
const cors = require('cors');
const mysql = require('mysql');
const bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(morgan('dev'));
app.use('*', cors());
app.listen(4600, () => {
console.log("Server listening on port 4600...");
});
//All users
app.get("/api/users", (req, res) => {
let connection = getConnection();
connection.query('SELECT * FROM USERS', (err, result) => {
if(err){
throw err;
}
console.log(result);
res.json(result);
});
});
//Specific user
app.get('/api/users/:id', (req, res) => {
getConnection().query('SELECT * FROM USERS WHERE ID = ?', req.params.id, (err, result) => {
if(err){
console.log(err.message);
throw err;
}
res.json(result);
});
});
//Update user
app.put("/api/users/:id", (req, res) => {
console.log('PUT request received...');
getConnection().query("UPDATE USERS SET FIRST_NAME = ?, LAST_NAME = ? WHERE ID = ?", [req.body.first_name, req.body.last_name, req.body.id], (err, result) => {
if(err){
console.log(err.message);
throw err;
}
res.send(201, req.body);
});
});
//Delete user
app.delete('/api/users/:id', (req, res) => {
});
function getConnection(){
return mysql.createConnection({
host: 'localhost',
user: '',
password: '',
database: 'test'
});
}
EDIT 1
Based on #tadman comment I searched for the Network tools available in my browser and I found out, as expected, that the POST request were being ignored. By subscribing to the http client, the POST requests started to be noticed as they should. The answer by #KeaganFouche in the question bellow helped me:
Angular 4.0 http put request
New update method in the Angular service:
updateUser(user: User): void{
console.log('Updating: ' + user);
console.log("http://localhost:4600/api/users/" + user.id);
this.http.put<void>("http://localhost:4600/api/users/" + user.id, user).subscribe((response) => {console.log(response)});
}
Based on #tadman comment I searched for the Network tools available in my browser and I found out, as expected, that the POST request were being ignored. By subscribing to the http client, the POST requests started to be noticed as they should. The answer by #KeaganFouche in the question bellow helped me: Angular 4.0 http put request
New update method in the Angular service:
updateUser(user: User): void{
console.log('Updating: ' + user);
console.log("http://localhost:4600/api/users/" + user.id);
this.http.put<void>("http://localhost:4600/api/users/" + user.id, user).subscribe((response) => {console.log(response)});
}
Hi I can't get data from nodejs by angular 6.
I added a service to connect between them but it is not working.
I succeed to get data by nodejs server, but I can't receive it on angular components.
I know that I missed something to connect between them but I can't resolve it.
HostingstartComponent.ts
import { Component, OnInit } from '#angular/core';
import { NgAnalyzedFile } from '#angular/compiler';
import {RouterModule ,Routes } from '#angular/router';
import {HttpModule, Http} from '#angular/http'
import { AngularFontAwesomeModule } from 'angular-font-awesome';
import { SecComponent } from '../sec/sec.component';
import { ThirdComponent } from '../third/third.component';
import {aService} from '../services/a.service';
#Component({
selector: 'app-hostingstart',
templateUrl: './hostingstart.component.html',
styleUrls: ['./hostingstart.component.css']
})
export class HostingstartComponent implements OnInit {
aService: any;
data: any;
appRoutes : Routes=[
{path: 'hostingstar',component : HostingstartComponent},
{path: '',component : HostingstartComponent},
{path: 'sec',component : SecComponent, data : {some_data : 'some value'}},
{path: 'third',component : ThirdComponent, data : {some_data : 'some value'}}
];
headImg : any="assets/images/pan.JPG";
constructor(private http: Http , private service: aService) {
this.headImg ="assets/images/pan.JPG";
// this.aService.getData().then( (result) => {this.data = result; });
}
ngOnInit() {
// alert(this.aService.getData());
// this.aService.getData().then( (result) => {this.data = result; });
// alert(this.data);
}
myFunc() {
//this.router.navigate(['/third', 'north']);
// alert( document.getElementById("search-input").value);
}
getData() {
this.aService.getData().subscribe((dataFromServer) => {
this.data=dataFromServer;
// Now you can use the data
// alert(dataFromServer)
console.log(dataFromServer);
});
}
}
aService.ts
import 'rxjs/add/operator/toPromise';
import { Http, Response, Headers } from '#angular/http';
import { Injectable } from '#angular/core';
#Injectable()
export class aService {
constructor(private http: Http) {
}
async getData() {
const options = {
headers: new Headers({
'Content-Type': 'application/json;charset=utf-8',
'Access-Control-Allow-Origin': '*'
})
};
// const url = './assets/heroes.data.json';
const url = 'http://localhost:3000/';
return this.http.get(url, options)
.toPromise()
.then(response => {
if (response != null) {
const result = response.json();
return Promise.resolve(result);
}
return [];
})
.catch(err => {
console.warn('error in getCats', err);
return Promise.reject(null);
});
}
}
Node js : index.js
console.log('Running File: index.js')
//-- Create Express Server:
var express = require('express');
var app = express();
var util = require('util');
var mysql = require('mysql');
var a;
var con = mysql.createConnection({
host : 'localhost',
user: 'node',
password : 'arafat1990!##$',
database: "iTour"
});
con.connect(function(err) {
if (err) throw err;
con.query("SELECT * FROM feedback", function (err, result, fields) {
if (err) throw err;
// console.log(result);
a=result;
});
});
//-- Map Base URL to res (Response)
app.get('/', function(req, res){
var fname = req.query.fname;
var lname = req.query.lname;
var html = util.format('<p>Hello %s %s</p>', a[1].username,a[0].rating);
res.send(a);
});
app.get('/hostingstar', function(req, res){
var fname = req.query.fname;
var lname = req.query.lname;
var html = util.format('<p>Hello %s %s</p>', a[1].username,a[0].rating);
res.send(a);
});
//-- Listen on Port 3000:
app.listen(3000);
app.js
const express = require('express');
const app = express();
//const firebase = require('firebase-admin');
app.get('/hostingstart', (req, res) => res.send('Server Is Active!'))
app.get('/hostingstart', (req, res) => {
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user: 'node',
password : 'arafat1990!##$',
database: "iTour"
});
connection.connect();
connection.query('SELECT * FROM feedback;', function (error, results, fields) {
if (error) {
console.warn(error);
res.send('');
return;
}
console.log("Result: " + results);
res.send(results);
});
connection.end();
})
app.get('/hostingstart', (req, res) => {
var ref = firebase.app().database().ref();
ref.once("value").then(function (snap) {
console.log("snap.val()", snap.val());
res.send(snap.val());
});
});
app.use(function(req, res, next){
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Credentials", "true");
res.setHeader("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
res.setHeader("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
// Check if preflight request
if (req.method === 'OPTIONS') {
res.status(200);
res.end();
}
else {
next();
}
});
app.listen(3000, () => console.log('Server is listening on port 3000!'))
In your getService method you are calling the service itself not the property from the constructor.
Your:
this.aService.getData()
Should be:
this.service.getData()
Additionally call myFunc() in ngOnInit
ngOnInit() {
this.myFunc()
}
I am using ionic2 to send requests to a local nodejs server, but the problem is that the request does not hit the server unless I set the header Content-Type to application/x-www-form-urlencoded , now the problem is that the body that arrives then is not a json file.
this is my ionic2 code
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import { Http, Headers } from '#angular/http';
import 'rxjs/add/operator/map';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
constructor(public navCtrl: NavController, public http: Http) {}
send(){
let headers = new Headers({
// 'Content-Type': 'application/json'
'Content-Type': 'application/x-www-form-urlencoded'
});
let body = {a: 'b'};
this.http.post('http://localhost:8010/api/test', body, {headers: headers})
.map(res => res.json())
.subscribe(data => {
console.log('response11: ', data);
}, err => {
console.log('ERR: ', err);
});
}
}
send is called inside a button with (click)='send()'
and this is my server code:
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.post('/api/test', function(req, res){
console.log(req.body);
res.send('from nodejs');
});
app.listen(8010);
console.log('listening on port 8010...');
when I print the body of this request to the console it prints like this
{ '{\n "a": "b"\n}': '' }
now if I change the Content-Type to application/json the server does not log anything and ionic page show error with status 0
so what is the proper way to send http POST or GET request from ionic2 to a node server ?
I believe you are facing a CORS issues. Enable CORS on your server, by doing the following on the server:
const cors = require("cors");
const originsWhitelist = [
"http://localhost:8100"
];
const corsOptions = {
origin: function (origin, callback) {
var isWhitelisted = originsWhitelist.indexOf(origin) !== -1;
callback(null, isWhitelisted);
},
credentials: true
};
//here is the magic
app.use(cors(corsOptions));