CORS not allowing access - node.js

I have looked at and troubleshot with many different posts on stack overflow of people having similar or the same issue, however, no solutions seem to work for me.
I keep getting the error
Access to XMLHttpRequest at 'http://localhost:3000/email?email=j' from origin 'https://mai...' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I thought adding app.use(cors()); would fix it, but the problem persists.
const path = require("path");
const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const mongoose = require("mongoose");
var userController = require("./controllers/userController.js");
var emailController = require("./controllers/emailController.js");
var app = express();
app.use(cors());
mongoose.connect(
"redactedForStackOverflow",
{ useUnifiedTopology: true, useNewUrlParser: true },
err => {
if (!err) console.log("MongoDB connection succeeded...");
else
console.log(
"Error in DB connection : " + JSON.stringify(err, undefined, 2)
);
}
);
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use("/", express.static(path.join(__dirname, "angular")));
var port = 3000;
app.listen(process.env.PORT || port, () =>
console.log("Server started at port : " + port)
);
app.use("/users", userController);
app.use("/email", emailController);
app.use((req, res, next) => {
res.sendFile(path.join(__dirname, "angular", "index.html"));
});
module.exports = app;
EDIT
Adding service file
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/operator/toPromise';
import { User } from './user.model';
import { UserComponent } from '../user/user.component';
#Injectable({
providedIn: 'root'
})
export class UserService {
selectedUser: User;
users: User[];
readonly baseURL = 'http://localhost:3000/users';
codeSentIn;
constructor(private http: HttpClient) {}
postUser(users: User) {
const codeOnItsWay = this.codeSentIn;
this.resetCode();
return this.http.post<any>(this.baseURL, {users, codeOnItsWay});
}
resetCode() {
this.codeSentIn = '';
}
getUserList() {
return this.http.get(this.baseURL);
}
getSpecificUser(id) {
return this.http.get<any>(this.baseURL + '/' + id);
}
findPositionInLine(email) {
return this.http.get<any>(this.baseURL + '/positionInLine/' + email);
}
getUserForLogin(email) {
return this.http.get(this.baseURL + '/login/' + email);
}
sendEmailToCheck(emailToCheck) {
return this.http.get('http://localhost:3000/email', { params: { email: emailToCheck }});
}
}

Update: possible missing cors option:
var corsOptions = {
origin: 'localhost:3000',
credentials : true
}
as mentioned from here : Node JS CORS module not setting Access-Control-Allow-Credentials header
Alternatively, Remove app.use(cors());
You can manually add header in all your requests :
app.use((req, res,next) => {
res.set('Access-Control-Allow-Origin', '*');
next();
});
Just add the above code block before
app.use("/users", userController);
app.use("/email", emailController);
app.use((req, res, next) => {
res.sendFile(path.join(__dirname, "angular", "index.html"));
});

Related

Access to XMLHttpRequest blocked by CORS when sending data from front-end to back-end using POST

Here is a bit of a background: I am making a full stack to-do list application. The front-end is based on React and Bootstrap. The backend is using Express, Node and MongoDB. The problem is that when I'm fetching the data from MongoDB using GET, I can view it on frontend. But when I'm sending the data using POST, I get this error:
Access to XMLHttpRequest at 'http://localhost:5035/api/todos' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I'm adding the required code files here.
Frontend
TodoTask.js
// Handles displaying components related to todo task list
import React, { useState, useEffect } from "react";
import TodoForm from "./TodoForm";
import TodoUpdate from "./TodoUpdate";
import axios from "axios";
function TodoTask() {
//for the list of tasks
const [todos, setTodos] = useState([]);
//add task in the list of tasks
const addTodo = async todo => {
//check for empty input
if (!todo.text || /^\s*$/.test(todo.text)) {
return
}
const newTodos = [todo, ...todos];
setTodos(newTodos);
console.log(todos);
try {
await axios.post("http://localhost:5035/api/todos", {
todo
});
} catch (error) {
console.log(error);
}
}
const ViewAllTodos = () => {
useEffect(() => {
getAllTodo();
}, []);
}
const getAllTodo = async () => {
const response = await axios.get("http://localhost:5035/api/todos");
setTodos(response.data.Todo);
console.log(response.data.Todo);
}
const updateTodo = (todoId, newValue) => {
if (!newValue.text || /^\s*$/.test(newValue.text)) {
return
}
setTodos(prev => prev.map(item => (item.id === todoId ? newValue : item)))
}
const removeTodo = id => {
const remove = [...todos].filter(todo => todo.id !== id);
setTodos(remove);
}
const completeTodo = id => {
let updatedTodos = todos.map(todo => {
if (todo.id === id) {
todo.isComplete = !todo.isComplete;
}
return todo;
});
setTodos(updatedTodos);
}
const [message, setMessage] = useState('');
return (
<div id="container">
<h1 className="display-1">My To Do List Application</h1>
<p className="lead">This is a basic to do list application with complete frontend and backend configuration. For details, check ReadMe.md of this project.</p>
{/* calling the form component to show a text field */}
<label htmlFor="formGroupExampleInput">Enter your to do here:</label>
<TodoForm onSubmit={addTodo} />
{/* checking if the list is empty, otherwise list all the todos with update and delete button */}
{todos.length === 0 ?
<p className="lead">The list is empty!</p> :
<TodoUpdate todos={todos} completeTodo={setTodos} removeTodo={removeTodo}
updateTodo={updateTodo} />
}
{/* {todos.length === 0 ? <p>Empty</p> :
todos.map((todo, index) => (
<tr key={todo._id}>
<td>{todo.priority}</td>
<td>{todo.todo}</td>
</tr>
))
} */}
</div>
)
}
export default TodoTask;
Backend:
MongooseServer.js
// import dependencies
const express = require('express');
var bodyParser = require('body-parser');
const mongoose = require('mongoose');
const router = require('./routers/routes');
const cors = require('cors');
// const dbUrl = require('./config/db.config/url')
// set up dependencies
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use('/api/', router);
const corsOptions ={
origin:'http://localhost:3000',
credentials:true, //access-control-allow-credentials:true
optionSuccessStatus:200,
methods: "GET, POST"
}
app.use(cors(corsOptions));
//app.use(cors());
// app.use(cors({
// origin: 'http://localhost:3000',
// }))
// set up mongoose
mongoose.connect("mongodb://127.0.0.1:27017/mytodolist")
.then(()=> {
console.log('Database connected');
})
.catch((error)=> {
console.log('Error connecting to database');
});
// set up port
const port = 5035;
// set up route
app.get('/', (req, res) => {
res.status(200).json({
message: 'Welcome to todo list',
});
});
app.listen(port, () => {
console.log(`Our server is running on port ${port}`);
});
Model.js
const mongoose = require("mongoose");
const MyTodoListSchema = new mongoose.Schema({
taskId: {
type: Number,
required: true,
unique: true
},
todo: {
type: String,
default: "",
required: true
},
priority: {
type: String,
default: "high",
required: true
},
});
const MyTodoList = mongoose.model("MyTodoList", MyTodoListSchema);
module.exports = MyTodoList;
Controller.js
// import mongoose from 'mongoose';
const mongoose = require('mongoose')
// import {MyTodoList} from '../models/model';
const MyTodoList = require('../models/model');
exports.createTodo = (req, res) => {
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "*");
next();
});
const todo = new MyTodoList({
taskId: req.body.taskId,
todo: req.body.todo,
priority: req.body.priority,
});
return todo
.save()
.then((newTodo) => {
return res.status(201).json({
success: true,
message: 'New todo list created successfully',
MyTodoList: newTodo,
});
})
.catch((error) => {
res.status(500).json({
success: false,
message: 'Server error. Please try again.',
error: error.message,
});
});
}
//get all todos
exports.getAllTodo = (req, res) => {
res.setHeader("Access-Control-Allow-Origin", "*")
res.setHeader("Access-Control-Allow-Credentials", "true");
res.setHeader("Access-Control-Max-Age", "1800");
res.setHeader("Access-Control-Allow-Headers", "content-type");
res.setHeader( "Access-Control-Allow-Methods", "PUT, POST, GET, DELETE, PATCH, OPTIONS" );
MyTodoList.find()
.select('taskId todo priority')
// .then( () => {
// res.setHeader("Access-Control-Allow-Origin", "*")
// res.setHeader("Access-Control-Allow-Credentials", "true");
// res.setHeader("Access-Control-Max-Age", "1800");
// res.setHeader("Access-Control-Allow-Headers", "content-type");
// res.setHeader( "Access-Control-Allow-Methods", "PUT, POST, GET, DELETE, PATCH, OPTIONS" );
// })
.then((allTodo) => {
// const response = res.status(200).json( {
// success: true,
// message: 'A list of all todos',
// Todo: allTodo
// });
return res.status(200).json({
// success: true,
// message: 'A list of all todos',
Todo: allTodo
});
// return response;
})
.catch((err) => {
res.status(500).json({
success: false,
message: 'Server error. Please try again.',
error: err.message,
});
});
}
// module.exports = {createTodo, getAllTodo}
Route.js
const express = require("express");
const cors = require("cors");
const todolist_controller = require('../controllers/controller')
const app = express();
const router = express.Router();
router.post('/todos', todolist_controller.createTodo);
router.get('/todos', todolist_controller.getAllTodo);
module.exports = router;
Please guide me on what I'm doing wrong here.
The POST is working fine with Postman. I'm using the MVC pattern for the application. Also, the frontend and backend are two separate directories inside one main directory. Both are running on different ports. Frontend is running on port 3000 and backend on port 5035.
TIA! I'm stuck on this for day. Please help out here!
If you would like to whitelist for all API endpoints then cors middleware must be called before your route(and this recommended also) like following
const app = express();
const corsOptions ={
origin:'http://localhost:3000',
credentials:true, //access-control-allow-credentials:true
optionSuccessStatus:200,
methods: "GET, POST"
}
app.use(cors(corsOptions));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use('/api/', router); // cors middleware must call before this line
Just use the cors middleware at the root of your api project with express for instance :
const cors = require('cors');
app.use(cors());

Angular Nodejs : Output is Undefined, Can't access the data from the server

I've just started programming in Node and Angular and I'm trying to run a simple application wherein I'm connecting my backend (localhost:3000) to my frontend and displaying the data. If the data I receive from the server when a get request is made is put in a .json file and I access it in the same folder then the data is being displayed.
But if I use the address of the api(http://localhost:3000/purchase) from which the data has been picked I get an undefined error in the browser.
This is the error it shows in the browser:
ContactsComponent.html:2 ERROR TypeError: Cannot read property 'Empno' of undefined
at Object.eval [as updateRenderer] (ContactsComponent.html:2)
at Object.debugUpdateRenderer [as updateRenderer] (core.js:22503)
at checkAndUpdateView (core.js:21878)
at callViewAction (core.js:22114)
at execComponentViewsAction (core.js:22056)
at checkAndUpdateView (core.js:21879)
at callViewAction (core.js:22114)
at execComponentViewsAction (core.js:22056)
at checkAndUpdateView (core.js:21879)
at callWithDebugContext (core.js:22767)
This is the Output from my server (http://localhost:3000/purchase) on Postman:
{
"Empno": "113 ",
"Ename": "Mary ",
"Sal": "15220 ",
"Deptno": "DP "
}
This is the code in angular for the service:
import { Injectable } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { HttpClient } from '#angular/common/http';
import 'rxjs/add/operator/map';
import { map, filter, switchMap, catchError } from 'rxjs/operators';
import { Contact } from './contact';
import { HttpErrorResponse, HttpResponse } from '#angular/common/http';
import { Observable, throwError } from 'rxjs';
import { retry } from 'rxjs/operators';
#Injectable({
providedIn: 'root'
})
export class ContactService {
contact: Contact[];
// configUrl1 = '../assets/test.json';
configUrl1 = 'http://localhost:3000';
constructor(private http: HttpClient) { }
// retrieving contacts
getPurchase() {
return this.http.get(this.configUrl1);
}
}
**This is the code for the Component:**
import { Component, OnInit } from '#angular/core';
import { ContactService } from '../contact.service';
import { Contact } from '../contact';
#Component({
selector: 'app-contacts',
templateUrl: './contacts.component.html',
styleUrls: ['./contacts.component.scss'],
providers: [ContactService]
})
export class ContactsComponent implements OnInit {
contact: Contact;
Empno: string;
Ename: string;
Sal: string;
Deptno: string;
constructor(private contactService: ContactService) { }
ngOnInit() {
this.contactService.getPurchase()
.subscribe((data: Contact) => this.contact = {...data});
}
}
This is the code for defining the structure for contact:
export class Contact {
Empno: string;
Ename: string;
Sal: string;
Deptno: string;
}
This is the code for the HTML file of the contact component:
<div class= "container">
<p>Its Working here also</p>
{{contact.Empno}}
{{contact.Ename}}
</div>
Server Side code:
App.js
//importing modules
var express = require('express');
var bodyParser = require('body-parser');
var cors = require('cors');
var mssql = require('mssql');
var path = require('path');
var app = express();
const route = require('./routes/route');
//port no
const port = 3000;
// adding middlewear - cors
app.use(cors());
// adding middlewear - bodyparser
// app.use(bodyparser.json());
// static files
app.use(express.static(path.join(__dirname, 'public')));
//creating routes
app.use('/purchase', route);
//testing
app.get('/', (req,res)=>{
res.send('foobar');
});
// //bind the port
app.listen(port, () => {
console.log('Server started at port: ' + port);
});
// create application/json parser
var jsonParser = bodyParser.json()
// app.use(bodyParser.json({ type: 'application/*+json' }))
// POST /login gets urlencoded bodies
app.post('/login', jsonParser, function (req, res) {
if (!req.body) return res.sendStatus(400)
res.send('welcome, ' + req.body.username)
})
route.js
const express = require('express');
const router = express.Router();
var bodyParser = require('body-parser');
var app = express();
const sql = require('mssql');
const config = 'mssql://vpn:vpn1#ASPL-AVG:1433/Sampledb';
app.use(bodyParser.json());
var jsonParser = bodyParser.json()
router.get('/', jsonParser,(req,res, next)=>{
var conn = new sql.ConnectionPool(config);
conn.connect().then((conn) => {
var sqlreq = new sql.Request(conn);
sqlreq.execute('SelEmpl10', function(err, recordset) {
res.json(recordset.recordsets[0][1]);
console.log(recordset.recordsets[0][1]);
})
})
});
//add purchase order
router.post('/' , jsonParser ,(req, res, next) => {
//logic to add record
console.log(req.body.username);
var conn = new sql.ConnectionPool(config);
conn.connect().then((conn) => {
var sqlreq = new sql.Request(conn);
sqlreq.input('Username', sql.VarChar(30), req.body.username);
sqlreq.input('Password', sql.VarChar(30), req.body.password);
sqlreq.input('Email', sql.VarChar(30), req.body.email);
sqlreq.input('Name', sql.VarChar(30), req.body.name);
sqlreq.execute('saveuser').then(function(err, recordsets, returnValue, affected) {
console.dir(recordsets);
console.dir(err);
conn.close();
}).catch(function(err) {
res.json({msg: 'Failed to add contact'});
console.log(err);
});
});
})
//delete purchase order
router.delete('/:id', (req, res, next) => {
//logic to delete record
});
module.exports = router;
The data received from SQL is this:
{
"recordsets": [
[
{
"Empno": "112 ",
"Ename": "john ",
"Sal": "142500 ",
"Deptno": "CS "
},
{
"Empno": "113 ",
"Ename": "Mary ",
"Sal": "15220 ",
"Deptno": "DP "
}
]
],
"recordset": [
{
"Empno": "112 ",
"Ename": "john ",
"Sal": "142500 ",
"Deptno": "CS "
},
{
"Empno": "113 ",
"Ename": "Mary ",
"Sal": "15220 ",
"Deptno": "DP "
}
],
"output": {},
"rowsAffected": [
2
],
"returnValue": 0
}
After adding the parameters in Node the output is this:
{
"Empno": "113 ",
"Ename": "Mary ",
"Sal": "15220 ",
"Deptno": "DP "
}
The issue is possibly connected to the use of bodyParser. It may be trying to parse already parsed JSON. Basically add the parser once at the top level and remove it from the routes. Also it may be connected to using json() instead of send(). I’ve had issues where if the data had a property named data, it could cause json parse/stringify to fail.
Try the following. In App.js reintroduce the line app.use(bodyParser.json()), this only needs to be added once at a top level location such as this entry file. Also from this file remove jsonParser middleware from the /login POST route:
var bodyParser = require('body-parser');
var app = express();
const route = require('./routes/route');
//port no
const port = 3000;
// adding middlewear - cors
app.use(cors());
// adding middlewear - bodyparser
app.use(bodyParser.json());
// static files
app.use(express.static(path.join(__dirname, 'public')));
//creating routes
app.use('/purchase', route);
//testing
app.get('/', (req,res)=>{
res.send('foobar');
});
// //bind the port
app.listen(port, () => {
console.log('Server started at port: ' + port);
});
// POST /login gets urlencoded bodies
app.post('/login', function (req, res) {
if (!req.body) return res.sendStatus(400)
res.send('welcome, ' + req.body.username)
})
In route.js, remove the bodyParser.json() and jsonParser middleware, it's already included at the top level as app.use(bodyParser.json()); applies it to all routes/verbs:
const express = require('express');
const router = express.Router();
var app = express();
const sql = require('mssql');
const config = 'mssql://vpn:vpn1#ASPL-AVG:1433/Sampledb';
router.get('/',(req, res, next)=>{
var conn = new sql.ConnectionPool(config);
conn.connect().then((conn) => {
var sqlreq = new sql.Request(conn);
sqlreq.execute('SelEmpl10', function(err, recordset) {
res.json(recordset.recordsets[0][1]);
console.log(recordset.recordsets[0][1]);
})
})
});
//add purchase order
router.post('/', (req, res, next) => {
//logic to add record
console.log(req.body.username);
var conn = new sql.ConnectionPool(config);
conn.connect().then((conn) => {
var sqlreq = new sql.Request(conn);
sqlreq.input('Username', sql.VarChar(30), req.body.username);
sqlreq.input('Password', sql.VarChar(30), req.body.password);
sqlreq.input('Email', sql.VarChar(30), req.body.email);
sqlreq.input('Name', sql.VarChar(30), req.body.name);
sqlreq.execute('saveuser').then(function(err, recordsets, returnValue, affected) {
console.dir(recordsets);
console.dir(err);
conn.close();
}).catch(function(err) {
res.json({msg: 'Failed to add contact'});
console.log(err);
});
});
})
// delete purchase order
router.delete('/:id', (req, res, next) => {
//logic to delete record
});
module.exports = router;
If that still fails, try just using res.send() instead of res.json(), even just for troubleshooting purposes.
The last thing that I'd recommend is sending an actual error or at least some type of 4xx or 5xx status code so that Angular HttpClient can treat it as an actual error instead of a successful HTTP request with a 200 status code.
Hopefully that helps!
Add a safe navigation operation to the contact variable.
<div class= "container">
<p>Its Working here also</p>
{{contact?.Empno}}
{{contact?.Ename}}
</div>
which is equivalent to contact != null ? contact.Empno: null
Update:
Also, add Error Handling code:
ngOnInit() {
this.contactService.getPurchase().subscribe(
(data: Contact) => {
this.contact = {...data};
},
error => {
console.log("Error Occured: "+ error);
}
);
}

Getting error Response with status: 404 Not Found for URL

I am facing an issue while running the angular and nodejs app which I am trying to integrate with Neo4j app. The issues are the errors that I get-
POST http://localhost:7474/viewNodesStart 404 (Not Found)
and
EXCEPTION: Response with status: 404 Not Found for URL:
http://localhost:7474/viewNodesStart
Though this topic is repetitive in StackOverflow , I am still posting it because the following links suggestions didn't suit my issue.
Angular2 404 Not Found for URL: http://localhost/WebApi2/api/hero
EXCEPTION: Response with status: 404 Not Found for URL / Angular2
https://github.com/johnpapa/angular-tour-of-heroes/issues/94
Please check my code
app.component.ts
import { Component, OnInit } from '#angular/core';
import { Injectable } from '#angular/core';
import { ToasterService } from '../toaster.service';
import { FormGroup, FormControl, FormBuilder, Validators } from '#angular/forms';
import { Http, Response, Headers } from '#angular/http';
import { config } from '../config';
import { Subject } from 'rxjs';
import 'rxjs/add/operator/map';
import { map } from 'rxjs/operators';
import 'rxjs/Rx';
import { Observable } from 'rxjs';
// Statics
import 'rxjs/add/observable/throw';
#Component({
selector: 'app-neo4j-primary',
templateUrl: './neo4j-primary.component.html',
styleUrls: ['./neo4j-primary.component.css']
})
export class Neo4jPrimaryComponent implements OnInit {
constructor(private http: Http, private notify: ToasterService) { }
ngOnInit() {
this.viewNodesStart();
}
emptyObj;
info;
// ------------------------------- Nodes Entire Data --------------
viewNodesStart() {
console.log("INSIDE viewNodesStart()")
// Nodes Value
console.log("inside Nodes Value");
var data = localStorage.getItem('token');
console.log("data is=>",data);
var url = config.url;
var port = config.port;
this.http.post("http://"+url+":"+port+"/viewNodesStart",this.emptyObj)
.map(Response => Response.json())
.subscribe((res: Response) => {
console.log("XXXXXXXXXXXX Response on /viewNodesStart", res);
this.info = res;
console.log('success', this.info.statusCode);
if (this.info.statusCode == 200) {
this.notify.Success("Data added successfully");
} else {
this.notify.Error("Data is not inserted")
}
});
}
}
server.js
var express = require('express');
var cors = require('cors');
var bodyParser = require('body-parser');
const neo4j = require('neo4j-driver').v1;
var app = express();
var restify = require('restify');
var expressJwt = require('express-jwt');
var session = require('express-session');
var config = require('./config.json')
app.use(restify.plugins.bodyParser());
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(bodyParser.json());
app.use(bodyParser.json({
type: 'application/vnd.api+json'
}))
app.use(cors());
app.use(session({
secret: config.secret,
resave: false,
saveUninitialized: true
}));
//*****TM Server ******/
app.use('/viewNodesStart', require('./neo4jserver/tmserver'));
app.get('/', function(req, res) {
res.send('Welcome');
console.log("welcome in console");
});
// start server
var server = app.listen(7473, function() {
console.log('Server listening at http://' + server.address().address + ':' + server.address().port);
});
nodeserver.js
// Require Neo4j
var neo4j = require('neo4j-driver').v1;
var path = require('path');
var logger = require('morgan');
var bodyParser = require('body-parser');
var express = require('express');
var router = express.Router();
var app = express();
// Create Driver
const driver = new neo4j.driver("bolt://localhost:11001",neo4j.auth.basic("neo4j", "abc"));
// Run Cypher query
const cypher = 'MATCH (n) RETURN count(n) as count';
//View Engine
app.set('views', path.join(__dirname, 'views'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(express.static(path.join(__dirname, 'public')));
var session = driver.session();
app.post('/', function(req, res) {
console.log("INSIDE NODE JS CONTROLLER OF viewNodesStart");
console.log("BODY IS ", req.body);
var log = JSON.parse(req.body);
console.log(log);
session.run('MATCH (n) RETURN n LIMIT 25').then(function(result) {
result.records.forEach(function(record) {
console.log("record", record);
console.log("result = ", result)
console.log("record._fields[0].properties", record._fields[0].properties);
res.status(200).send({
statusCode: '200',
result: result
});
});
}).catch(function(err) {
console.log(err);
}).then(res=>{
console.log("res.records.length", res.records.length);
}
)
res.send('It Works');
res.send(result);
});
var allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type');
if (req.method === "OPTIONS")
res.send(200);
else
next();
}
console.log('Server started on port 11005');
module.exports = router;
module.exports = app;
I guess the problem is with the url you are passing to the http request. You are passing the path of the anuglar route and want to call the node api.
Change the url there to the nodeapi url. Then it will work.

How to read data in node.js app.js from IONIC typescript through REST API?

My service.ts is like this :
import { Injectable } from '#angular/core';
import {Http, Headers} from '#angular/http';
import 'rxjs/add/operator/map';
/*
Generated class for the PeopleSearch provider.
See https://angular.io/docs/ts/latest/guide/dependency-injection.html
for more info on providers and Angular 2 DI.
*/
#Injectable()
export class PeopleSearch {
data: {name:'morr', age: 19, email:'mor#mo.com' };
apiurl: "http://localhost:3082";
constructor(public http: Http) {
console.log('Hello PeopleSearch Provider');
}
load1() {
return new Promise(resolve => {
let headers = new Headers();
this.http.post('http://localhost:3082/users/u/',JSON.stringify(this.data),{ headers: headers })
.map(res => res.json())
.subscribe(data => {
//console.log(data.user1);
resolve(data);
});
});
}
And my app.js is like this :
const express= require('express')
const app= express();
const morgan= require('morgan')
const mysql= require('mysql')
var cors = require('cors');
app.use(cors());
const bodyParser = require('body-parser')
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
const connection= mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'test'
})
app.use(morgan('combined'))
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With");
res.header("Access-Control-Allow-Methods", "GET, PUT, POST");
if ('OPTIONS' === req.method) {
res.status(204).send();
}
else {
next();
}
});
app.post("/users/u", (req, res) => {
const name=req.body.name
const age= req.body.age
const email= req.body.email
const querystring="insert into users values(?,?,?,?)"
connection.query(querystring, [11,name,age,email],(err,results,fields)=>{
console.log("success sql post")
res.end()
})
})
app.listen(3082, () => {
console.log("Server is up and listening on 3082...")
})
I am not getting where I am exactly wrong. If I write data hardcoded in all variables, username age and email, then post req is executing successfully. But when I am using req.body to get the data posted by typescript then i think Its not reading properly.
can anyone suggest what to use or how to use req.body to get the data in variables and save it in query??
You have not defined your data correctly in the PeopleSearch service. Take a close look at the top of the PeopleSearch class. This:
#Injectable()
export class PeopleSearch {
data: {name:'morr', age: 19, email:'mor#mo.com' };
apiurl: "http://localhost:3082";
Should be (note the '=' instead of ':'):
#Injectable()
export class PeopleSearch {
data = {name:'morr', age: 19, email:'mor#mo.com' };
apiurl = "http://localhost:3082";
The Typescript syntax for defining a property in a class is:
[name]:[type] = [value]
In your case you have defined the name and the type but not the value. Effectively you defined the property data and set the type so only objects exactly matching the properties and values you defined can be set to it.

How to make post request from angular to node server

When I print contents of request on Node server, I can't see the user data anywhere.
Here is my Node server:
var http = require('http');
http.createServer( function (request, response) {
console.log(request);
}).listen(8080);
console.log('Server running at http://127.0.0.1:8080/');
And here is Angular2 code:
import { Component, OnInit } from '#angular/core';
import { HttpClient } from "#angular/common/http";
import { Http, Response, Headers , RequestOptions } from "#angular/http";
import 'rxjs/add/operator/retry'; // to be able to retry when error occurs
import { Observable } from "rxjs/Rx";
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{
title = 'Angular Test';
user = { id : 1, name : "Hello"};
constructor (private http: Http) {}
ngOnInit(): void {
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
console.log(this.user);
this.http.post("http://localhost:8080/", this.user, options)
.subscribe(
(err) => {
if(err) console.log(err);
console.log("Success");
});
}
}
Can anyone help me out or explain how to handle http request in angular.
That is your server:
const express = require('express')
const bodyParser = require('body-parser');
const app = express()
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}) );
app.all("/*", function(req, res, next){
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');
next();
});
app.post('/ping', function (req, res) {
res.send(req.body)
})
app.listen(3000, function () {
console.log('Example app listening on port 3000!')
})
That is your angular client:
import { Component } from '#angular/core';
import { HttpClient, HttpHeaders } from '#angular/common/http';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
user = { id : 1, name : 'Hello'};
constructor(private http: HttpClient) { }
callServer() {
const headers = new HttpHeaders()
.set('Authorization', 'my-auth-token')
.set('Content-Type', 'application/json');
this.http.post('http://127.0.0.1:3000/ping', JSON.stringify(this.user), {
headers: headers
})
.subscribe(data => {
console.log(data);
});
}
}
repo https://github.com/kuncevic/angular-httpclient-examples
I've written this inside our documentation page but since it is deprecated now I'll copy it here.
Your node part, app.js, should look like (assuming you are using expressjs along with node.js):
app.js:
var express = require('express');
var app = express();
var server = require('http').Server(app);
var bodyParser = require('body-parser');
server.listen(process.env.PORT || 8080, function(){
console.log("Server connected. Listening on port: " + (process.env.PORT || 8080));
});
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}) );
app.use( express.static(__dirname + '/front' ) );
app.post('/test', function(req,res){ //**** http request receiver ****
var myTestVar = "Hello World";
return res.send(myTestVar);
});
//send the index.html on every page refresh and let angular handle the routing
app.get('/*', function(req, res, next) {
console.log("Reloading");
res.sendFile('index.html', { root: __dirname });
});
With this node configs when you post something to localhost:8080/test, you will receive myTestVar as a response in your subscribe callback.

Resources