Angular route is not working in Combined MEAN? - node.js

I created a single page app using Angular.I'm using Node/Express on the back-end. While Express is serving my static index.html correctly.
When i try to navigation to some angular route from url address bar it saying cannot get /login...
i found this question on stackoverflow it is exactly what i am saying but its not answered yet.
Angular - Routing is not working (MEAN)
Here is my code.
var path = require("path");
var express = require("express");
var mongoose = require("mongoose");
var app = express();
require('./startups/prod')(app);
// Temp.
const TempRoutes = require("./routes/temp");
mongoose.connect('mongodb://localhost:27017/node-angular', { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => {
console.log("Connected to database.");
})
.catch(() => {
console.log("Connection Failed.");
});
app.use(express.json());
app.use("/", express.static(path.join(__dirname, "dist")));
app.use((request, response, next) => {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader(
"Access-Control-Allow-Headers",
"Origin, X-Requesed-With, Content-Type, Accept,Accept-Language,Content-Language, Authorization");
response.setHeader(
"Access-Control-Allow-Methods",
"GET, POST, PATCH, PUT, DELETE, OPTIONS");
next();
});
app.use((request, response, next) => {
response.sendFile(__dirname, path.join("dist", "index.html"))
})
module.exports = app;

Related

MeanStack: blocked by cors on Linux(ubuntu)

I'm doing this MeanStack course and I managed to create several files with post routes along with their schemas. But the last file I created, shopping cart schema and its route is getting blocked by cors. I tried to move the path to the files where the post works but still, get blocked, thought yesterday this workaround actually worked, but today is not working anymore. I've tried even to add an extension to chrome but nothing is working. On windows I can easily disable the cors, but not on linux
app.js
const express = require("express");
const bodyParser = require("body-parser");
const mongoose = require("mongoose");
const postsRoutes = require("./routes/posts");
const userRoutes = require("./routes/user");
const nasaRoutes = require("./routes/nasa");
const movieRoutes = require("./routes/movies");
const shoppingCartRoutes = require("./routes/shoppingCart");
const app = express();
mongoose
.connect('mongodb+srv://icenine:qN4pI8Tuy0chs7qK#mean-robot-cluster.zyjkf.mongodb.net/Mean-Robot-Cluster?retryWrites=true&w=majority'
)
.then(() => {
console.log("Connected to database!");
})
.catch(() => {
console.log("Connection failed!");
});
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization"
);
res.setHeader(
"Access-Control-Allow-Methods",
"GET, POST, PATCH, PUT, DELETE, OPTIONS"
);
next();
});
app.use("/api/posts", postsRoutes);
app.use("/api/user", userRoutes);
app.use("/api/nasa", nasaRoutes);
app.use("/api/movies", movieRoutes);
app.use("api/shoppingCart", shoppingCartRoutes)
module.exports = app;
the shopping cart schema
const mongoose = require('mongoose');
const shoppingCartSchema = mongoose.Schema({
dateCrated: { type: Number, required: true },
});
module.exports = mongoose.model('ShoppingCart', shoppingCartSchema);
the route:
const express = require("express");
const ShoppingCart = require("../models/shoppingCart");
const router = express.Router();
router.post("", (req, res, next) => {
const cart = new ShoppingCart({
date:req.body.date
});
console.log(req.body)
cart.save().then(createdCart => {
res.status(201).json({
message: "Cart created successfully",
cartId: createdCart._id
});
})
.catch(err => {
res.status(500).json({
error: err
});
});
});
The Front End Angular (service)
createCart(){
let date={dateCreated: new Date().getTime()}
return this.http.post<{message:string, cartId:string}>('http://localhost:3000/api/shoppingCart', date)
}
Component
addToCart(product:Product){
let cartId = localStorage.getItem('cartId')
if(!cartId){
this.shoppingService.createCart()
.subscribe(result =>{
localStorage.setItem('cartId', result.cartId);
});
}//etc
}
The console error (front end)
The solution for Linux -Ubuntu is to open the terminal and simply type:
google-chrome --disable-web-security --user-data-dir=/tmp
You are trying to access your API which is on a different port and that's causing the cors issue, at least in the localhost environment.
you can use the cors package to allow cross-origin access.
...
const cors = require("cors");
...
app.use(cors());
...
If this is only a local project you can leave it as is or you can pass parameters to the cors function if you gonna publish your project to limit the origins allowed to access your API.

Backend Node routes not working after heroku deployment

I have recently deployed my node.js backend using Heroku but now it seems like my routes don't work anymore. It always goes through my error route to return "Could not find this route." This did not happen when I was using localhost whilst developing.
app.js:
const express = require('express');
const bodyParser = require('body-parser');
const HttpError = require('./models/httpError');
const questionRoutes = require('./routes/questionRoutes');
const app = express();
app.use(bodyParser.json());
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader(
'Access-Control-Allow-Headers',
'Origin, X-Requested-With, Content-Type, Accept, Authorization'
);
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PATCH, DELETE');
next();
});
app.use('/api/questions', questionRoutes);
app.use((req, res, next) => {
console.log(req.url);
const error = new HttpError('Could not find this route.', 404);
throw error;
});
app.use((error, req, res, next) => {
if (res.headerSent) {
return next(error);
}
res.status(error.code || 500);
res.json({ message: error.message || 'An unknown error occurred!' });
});
app.listen(process.env.PORT || 5000);
I am not using any environment variables. Here is the heroku link to my backend: https://mealoftheday.herokuapp.com/
Any help would be appreciated!
router.get('*', (request, response) => {
response.sendFile(path.join(__dirname, 'etsa2/build', 'index.html'));
});
Add this file to your routes my issue was solved hope yours too get solved

How to perform PUT in Node JS

Below is my app.js code.
import bodyParser from 'body-parser';
import cors from 'cors';
import requestIp from 'request-ip';
import os from 'os';
import { AppRoutes, AuthRoutes } from './routes';
const app = express();
app.use(cors());
app.disable('x-powered-by');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use((req, res, next)=> {
const clientIp = requestIp.getClientIp(req);
logger.debug(JSON.stringify(req.socket.address()));
logger.debug(`incoming IP ${clientIp}`);
next();
});
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");
res.header('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');
next();
});
// Api Routes.
app.use('/api/login', AppRoutes);
app.use('/api', verifyToken, AuthRoutes);
export default app;
Below is my index.js code. Below code is working fine for GET and POST but its not working for PUT. Its giving an error.
You don't have permission to access /api/save-user-profile/{user-name}.
import {
getCustomersbyId
} from './controller/customer-controller';
import { Login } from './controller/login';
import {
modelEdit,
saveProfile
} from './controller/extension';
const AuthRoutes = Router();
const AppRoutes = Router();
AuthRoutes.get('/customers/', getCustomersbyId);
AuthRoutes.post('/model-entity-links/info', modelEdit);
AuthRoutes.put('/save-user-profile/:username', saveProfile);
AppRoutes.post('/', Login);
export { AuthRoutes, AppRoutes };
When I am changing PUT to POST it is working fine. But I want to do it using PUT. Am I missing here anything to configure PUT.
I have tried below code as well in app.js. But still getting same issue.
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');
My saveProile code is as below.
export const saveUserProfile = (req, res) => {
logger.debug({ method: 'saveUserProfile', message: MESSAGE.ENTER });
const { username } = req.params;
const userProfileInfo = JSON.parse(JSON.stringify(req.body));
if (username && !isEmptyObject(userProfileInfo)) {
postUserProfile(username, userProfileInfo)
.then(r=>{
res.status(200).send(r.data);
})
.catch(e=>{
logger.error({ method: 'saveUserProfile', message: e.response ? JSON.stringify(e.response.data.response_message) : e });
parseError(e, res);
});
} else {
logger.error({ method: 'saveUserProfile', message: MESSAGE.ERROR_INVALID_PARAM });
parseError(MESSAGE.ERROR_INVALID_PARAM, res, true);
}
};
I have resolved this issue. It was an apache server issue where PUT and DELETE operation was restricted. We have made changes in apache configuration and it worked. Thank you all for responses.

React Express Fetch Post CORS error: Response to preflight request doesn't pass access control check: It does not have HTTP ok status

I'm trying to set up a basic user signup form with React, Node, and Express, and using fetch. However, I'm getting the following errors in the Chrome console when I try and send a post request:
1) "OPTIONS http://localhost:7001/v1/register 500 (Internal Server Error)"
2) "Access to fetch at 'http://localhost:7001/v1/register' from origin 'http://localhost:3001' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status."
My eventual goal is to save the user's email and password in a database, but for now all I want is for the request to go through to the backend and have the backend log the body to make sure everything works. I've tried several different ways of setting headers, and I have no idea what's wrong. Below is the code.
Frontend form submit function:
handleSubmit(e) {
e.preventDefault();
const signUpInfo = this.state; // { email: 'test#gmail.com', password: '123' }
console.log(signUpInfo);
fetch('http://localhost:7001/v1/register', {
method: 'POST',
body: JSON.stringify(signUpInfo),
headers: {
'Content-Type': 'application/json'
}
})
.then(res => res.json())
.then(response => console.log('Success:', response))
.catch(error => console.error('Error:', error));
}
server.js
const express = require('express');
const compression = require('compression');
const cfg = require('config');
const path = require('path');
const logger = require('morgan');
const cookieParser = require('cookie-parser')
const bodyParser = require('body-parser');
const config = require('config');
const app = express();
app.use(compression());
app.use(bodyParser());
app.use(cookieParser());
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.static(path.join(__dirname, 'public')));
app.use(function(req, res, next) {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,DELETE");
res.setHeader("Access-Control-Allow-Headers", "X-Requested-With, Access-Control-Allow-Headers, Content-Type, Authorization, Origin, Accept");
res.setHeader('Access-Control-Allow-Credentials', true)
next();
});
// CONTROLLERS
const userController = require('./controllers/userController.js');
// ROUTES
app.post('/v1/register', userController.register);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
app.listen('7001', function() {
console.log('API server listening on port 7001!');
});
module.exports = app;
userController.js
exports.register = async (req, res, next) => {
try {
console.log(req.body);
res.status(200).json({ status: 200, data: req.body, message: "test" });
} catch (err) {
console.log(err);
res.status(500).json({ status: 500, data: null, message: err });
}
}
All I'm looking for is for the backend console to print out the body. It works with axios and $.ajax, but not with fetch. I've also tried using a proxy server to no avail (and would like to get it to work without a proxy).
Not sure if this is relevant, but I'm using Chrome as the browser and Sequelize.
Any help would be greatly appreciated. I feel like I'm missing something fundamental. Any helpful articles to deepen my learning would be a plus!
Instead of using
const app= express();
try to use
const app=express().use('*', cors());
and remove
app.use(function(req, res, next) {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,DELETE");
res.setHeader("Access-Control-Allow-Headers", "X-Requested-With, Access-Control-Allow-Headers, Content-Type, Authorization, Origin, Accept");
res.setHeader('Access-Control-Allow-Credentials', true)
next();
});
see if this works.
First Install "cors":
npm i cors
Second import "cors":
cors = reqquire("cors");
Third use "cors":
const app = express();
app.use("*", cors());

How do I pass a const to my scope

I m trying to use the node-binance-api to retreive cryptocurency value.
I am able to get the information and display it in the node console.
Im doing so like this;
var express = require('express');
var app = express();
var mongo = require('mongodb');
var db = require('mongojs')("mongodb://URL")
var nodeBinanceApi = require("node-binance-api");
const binance = require('node-binance-api')().options({
APIKEY: '***',
APISECRET: '***',
useServerTime: true, // If you get timestamp errors, synchronize to server time at startup
test: true // If you want to use sandbox mode where orders are simulated
});
app.use(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", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
binance.prices((error, ticker) => {
console.log("Price: ", ticker); <--------------------------
console.log("Price of BTC: ", ticker.BTCUSDT);
});
app.use(express.static(__dirname + '/www'));
app.listen(81);
I would like to pass the json information in ticker to my scope in another script on the page. Should i use routes? and the use get request in the scope?
It does work with routes!
I added
app.get('/crypto', function(req, res){
//calling the function
binance.prices((error, ticker) => {
res.jsonp(ticker);
console.log(ticker);
});
return;
});
Now I can see the prices of all cryptosurrency on my page!

Resources