Issue
I followed this tutorial https://www.positronx.io/angular-8-mean-stack-tutorial-build-crud-angular-material/ to create a MEAN app
My express API works via curl and data successfully populates the mongo database. My angular front end also works in a live browser using nginx as the server. I am also able to proxy_pass to use express to serve the angular STATIC files directly.
When I try to POST data into a form from the browser I get an error saying ERR_CONNECTION_REFUSED. I have been stuck on this for a few days and not sure how I can resolve this. I suspect the issue is with my nginx file or /sites-available/default file, given that curl works in the command line.
My key files are:
/etc/nginx/sites-available/default:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
app.js (for express):
let express = require('express'),
path = require('path'),
mongoose = require('mongoose'),
cors = require('cors'),
bodyParser = require('body-parser'),
dataBaseConfig = require('./database/db');
// Connecting mongoDB
mongoose.Promise = global.Promise;
mongoose.connect(dataBaseConfig.db, {
useNewUrlParser: true,
useFindAndModify: false
}).then(() => {
console.log('Database connected sucessfully ')
},
error => {
console.log('Could not connected to database : ' + error)
}
);
// Set up express js port
const studentRoute = require('./routes/student.route');
const app = express();
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(bodyParser.json());
app.use(cors());
// Setting up static directory
app.use(express.static('../dist/meanstack'));
// RESTful API root
app.use('/api', studentRoute);
// PORT
const port = process.env.PORT || 3000;
app.listen(port, () => {
console.log('Connected to port ' + port);
})
// Find 404 and hand over to error handler
app.use((req, res, next) => {
next(createError(404));
});
// Index Route
app.get('/', (req, res) => {
res.send('invaild endpoint');
});
app.get('*', (req, res) => {
res.sendFile('../dist/meanstack/index.html');
});
//error handler
app.use(function (err, req, res, next) {
console.error(err.message);
if (!err.statusCode) err.statusCode = 500;
res.status(err.statusCode).send(err.message);
});
And the angular api.service file that connects the backend and front end:
import { Injectable } from '@angular/core';
import { Student } from './student';
import { Observable, throwError } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class ApiService {
endpoint: string = 'http://localhost:3000/api';
headers = new HttpHeaders().set('Content-Type', 'application/json');
constructor(private http: HttpClient) { }
// Add student
AddStudent(data: Student): Observable<any> {
let API_URL = `${this.endpoint}/add-student`;
return this.http.post(API_URL, data)
.pipe(
catchError(this.errorMgmt)
)
}
// Get all students
GetStudents() {
return this.http.get(`${this.endpoint}`);
}
// Get student
GetStudent(id): Observable<any> {
let API_URL = `${this.endpoint}/read-student/${id}`;
return this.http.get(API_URL, { headers: this.headers })
.pipe(
map((res: Response) => {
return res || {}
}),
catchError(this.errorMgmt)
)
}
// Update student
UpdateStudent(id, data): Observable<any> {
let API_URL = `${this.endpoint}/update-student/${id}`;
return this.http.put(API_URL, data, { headers: this.headers })
.pipe(
catchError(this.errorMgmt)
)
}
// Delete student
DeleteStudent(id): Observable<any> {
var API_URL = `${this.endpoint}/delete-student/${id}`;
return this.http.delete(API_URL)
.pipe(
catchError(this.errorMgmt)
)
}
// Error handling
errorMgmt(error: HttpErrorResponse) {
let errorMessage = '';
if (error.error instanceof ErrorEvent) {
// Get client-side error
errorMessage = error.error.message;
} else {
// Get server-side error
errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`;
}
console.log(errorMessage);
return throwError(errorMessage);
}
}
I am adding ./routes/student.route.js
const express = require('express');
const app = express();
const studentRoute = express.Router();
// Student model
let Student = require('../database/model/Student');
// Add Student
studentRoute.route('/add-student').post((req, res, next) => {
Student.create(req.body, (error, data) => {
if (error) {
return next(error)
} else {
res.json(data)
}
})
});
// Get all student
studentRoute.route('/').get((req, res) => {
Student.find((error, data) => {
if (error) {
return next(error)
} else {
res.json(data)
}
})
})
// Get single student
studentRoute.route('/read-student/:id').get((req, res) => {
Student.findById(req.params.id, (error, data) => {
if (error) {
return next(error)
} else {
res.json(data)
}
})
})
// Update student
studentRoute.route('/update-student/:id').put((req, res, next) => {
Student.findByIdAndUpdate(req.params.id, {
$set: req.body
}, (error, data) => {
if (error) {
return next(error);
console.log(error)
} else {
res.json(data)
console.log('Student successfully updated!')
}
})
})
// Delete student
studentRoute.route('/delete-student/:id').delete((req, res, next) => {
Student.findByIdAndRemove(req.params.id, (error, data) => {
if (error) {
return next(error);
} else {
res.status(200).json({
msg: data
})
}
})
})
module.exports = studentRoute;
I welcome any tips as this is the final step before I am able to make my first MEAN app tutorial go live. Please let me know if you need any clarifications. Thank you.
EDIT 1: I have added the ./routes/student.route.js file. After more reading I am wondering if the issue might be cors related.
EDIT 2: I added a screengrab of curl output from the terminal
EDIT 3: I have tried nginx cors as described here https://enable-cors.org/server_nginx.html with and without proxy_pass to express and that has not resolved this issue either
Solution
This has now been solved. The issue was with the api.service file in angular
endpoint: string = 'http://localhost:3000/api';
Here localhost:3000 should be replaced with the domain name
endpoint: string = 'http://www.example.com/api';
Answered By - Zakoff
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.