Reputation: 17
I have problem in ticket sistem. The post ticket is work but comment ticket does not work. Erro: Failed to load http://localhost:3977/api/tickets/comment: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. The response had HTTP status code 400.
Follow Code: Frontend:
// Function to create new ticket form
createNewTicketForm() {
this.form = this.formBuilder.group({
// Title field
title: ['', Validators.compose([
Validators.required,
Validators.maxLength(50),
Validators.minLength(5),
this.alphaNumericValidation
])],
// Body field
body: ['', Validators.compose([
Validators.required,
Validators.maxLength(500),
Validators.minLength(5)
])]
})
}
// Create form for posting comments
createCommentForm() {
this.commentForm = this.formBuilder.group({
comment: ['', Validators.compose([
Validators.required,
Validators.minLength(1),
Validators.maxLength(200)
])]
})
}
// Enable the comment form
enableCommentForm() {
this.commentForm.get('comment').enable(); // Enable comment field
}
// Disable the comment form
disableCommentForm() {
this.commentForm.get('comment').disable(); // Disable comment field
}
// Enable new ticket form
enableFormNewTicketForm() {
this.form.get('title').enable(); // Enable title field
this.form.get('body').enable(); // Enable body field
}
// Disable new ticket form
disableFormNewTicketForm() {
this.form.get('title').disable(); // Disable title field
this.form.get('body').disable(); // Disable body field
}
// Validation for title
alphaNumericValidation(controls) {
const regExp = new RegExp(/^[a-zA-Z0-9 ]+$/); // Regular expression to perform test
// Check if test returns false or true
if (regExp.test(controls.value)) {
return null; // Return valid
} else {
return { 'alphaNumericValidation': true } // Return error in validation
}
}
// Function to display new ticket form
newTicketForm() {
this.newPost = true; // Show new ticket form
}
// Reload tickets on current page
reloadTickets() {
this.loadingTickets = true; // Used to lock button
this.getTickets(); // Add any new tickets to the page
setTimeout(() => {
this.loadingTickets = false; // Release button lock after four seconds
}, 4000);
}
// Function to post a new comment on ticket post
draftComment(id) {
this.commentForm.reset(); // Reset the comment form each time users starts a new comment
this.newComment = []; // Clear array so only one post can be commented on at a time
this.newComment.push(id); // Add the post that is being commented on to the array
}
// Function to submit a new ticket post
onTicketSubmit() {
this.processing = true; // Disable submit button
this.disableFormNewTicketForm(); // Lock form
// Create ticket object from form fields
const ticket = {
title: this.form.get('title').value, // Title field
body: this.form.get('body').value, // Body field
createdBy: this.username // CreatedBy field
}
// Function to save ticket into database
this._ticketService.newTicket(this.token, ticket ).subscribe(data => {
// Check if ticket was saved to database or not
if (!data.success) {
this.messageClass = 'alert alert-danger'; // Return error class
this.message = data.message; // Return error message
this.processing = false; // Enable submit button
this.enableFormNewTicketForm(); // Enable form
} else {
this.messageClass = 'alert alert-success'; // Return success class
this.message = data.message; // Return success message
this.getTickets();
// Clear form data after two seconds
setTimeout(() => {
this.newPost = false; // Hide form
this.processing = false; // Enable submit button
this.message = false; // Erase error/success message
this.form.reset(); // Reset all form fields
this.enableFormNewTicketForm(); // Enable the form fields
}, 2000);
}
});
}
// Function to go back to previous page
goBack() {
window.location.reload(); // Clear all variable states
}
// Function to get all tickets from the database
getTickets() {
// Function to GET all tickets from database
this._ticketService.getTickets(this.token).subscribe(data => {
this.ticketPosts = data.tickets; // Assign array to use in HTML
});
}
// Function to post a new comment
postComment(id) {
this.disableCommentForm(); // Disable form while saving comment to database
this.processing = true; // Lock buttons while saving comment to database
const comment = this.commentForm.get('comment').value; // Get the comment value to pass to service function
// Function to save the comment to the database
this._ticketService.postComment(this.token, comment).subscribe(data => {
this.getTickets(); // Refresh all tickets to reflect the new comment
const index = this.newComment.indexOf(id); // Get the index of the ticket id to remove from array
this.newComment.splice(index, 1); // Remove id from the array
this.enableCommentForm(); // Re-enable the form
this.commentForm.reset(); // Reset the comment form
this.processing = false; // Unlock buttons on comment form
if (this.enabledComments.indexOf(id) < 0) this.expand(id); // Expand comments for user on comment submission
});
}
Backend:
function saveTicket(req, res){
if (!req.body.title) {
res.json({ success: false, message: 'Ticket title is required.' }); // Return error message
} else {
// Check if ticket body was provided
if (!req.body.body) {
res.json({ success: false, message: 'Ticket body is required.' }); // Return error message
} else {
// Create the ticket object for insertion into database
const ticket = new Ticket({
title: req.body.title, // Title field
body: req.body.body, // Body field
createdBy: req.body.createdBy // CreatedBy field
});
ticket.save((err, ticketStored) => {
// Check if error
if (err) {
// Check if error is a validation error
if (err.errors) {
// Check if validation error is in the title field
if (err.errors.title) {
res.json({ success: false, message: err.errors.title.message }); // Return error message
} else {
// Check if validation error is in the body field
if (err.errors.body) {
res.json({ success: false, message: err.errors.body.message }); // Return error message
} else {
res.json({ success: false, message: err }); // Return general error message
}
}
} else {
res.json({ success: false, message: err }); // Return general error message
}
} else {
res.json({ success: true, message: 'Ticket Salvo' }); // Return success message
}
});
}
}
};
function saveComment(req, res){
// Check if comment was provided in request body
if (!req.body.comment) {
res.json({ success: false, message: 'No comment provided' }); // Return error message
} else {
// Check if id was provided in request body
if (!req.body.id) {
res.json({ success: false, message: 'No id was provided' }); // Return error message
} else {
// Use id to search for ticket post in database
Ticket.findOne({ _id: req.body.id }, (err, ticket) => {
// Check if error was found
if (err) {
res.json({ success: false, message: 'Invalid ticket id' }); // Return error message
} else {
// Check if id matched the id of any ticket post in the database
if (!ticket) {
res.json({ success: false, message: 'Ticket not found.' }); // Return error message
} else {
// Grab data of user that is logged in
User.findOne({ _id: req.decoded.userId }, (err, user) => {
// Check if error was found
if (err) {
res.json({ success: false, message: 'Something went wrong' }); // Return error message
} else {
// Check if user was found in the database
if (!user) {
res.json({ success: false, message: 'User not found.' }); // Return error message
} else {
// Add the new comment to the ticket post's array
ticket.comments.push({
comment: req.body.comment, // Comment field
commentator: user.username // Person who commented
});
// Save ticket post
ticket.save((err, ticketStored) => {
// Check if error was found
if (err) {
res.json({ success: false, message: 'Something went wrong.' }); // Return error message
} else {
res.json({ success: true, message: 'Comment saved' }); // Return success message
}
});
}
}
});
}
}
});
}
}
};
Routes:
api.post('/ticket', md_auth.ensureAuth, TicketController.saveTicket);
api.post('/tickets/comment/', md_auth.ensureAuth, TicketController.saveComment);
Someone give me help? Ragards, Santana Marcos
Upvotes: 0
Views: 296
Reputation: 20744
Looks like a common CORS issue. If you are using Angular CLI (and I guess it's so), then you probably need to configure proxy for api-requests from dev-server 4200 port to api-server 3977 port. The official doc is here. Follow it and create appropriate config file and set --proxy-config
option to the npm ng serve
script:
proxy.conf.json
{
"/api": {
"target": "http://localhost:3977",
"secure": false
}
}
package.json
"start": "ng serve --proxy-config proxy.conf.json"
The requests form your front end (TicketService) should be like following
this.http.post('/api/tickets/comment', ...
And the handling on the back end
api.post('/api/tickets/comment', ...
Upvotes: 1