2

I'm making a web app with angular on the frontend, and golang and mongo on the backend for the database. I have the db up and running, and all route requests have been tested and are working on Postman. However, when I try to make DELETE request or PUT request on the service of the angular app, I get hit with the following error:

"Access to XMLHttpRequest at '-my api url-' from origin 'http://localhost:4200' 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 can make GET and POST requests, but not DELETE or PUT.

How do I get around this? Is this a frontend issue, or backend? Any help will be appreciated. Thank you.

PS: I'm using mongoHandlers.

Here's my service on the front end:

deleteShow(showId: string) {
    let headers = new HttpHeaders();
    headers.append("Content-Type", "application/json");
    return this.http
      .delete<Show>(`${environment.apiBase}/shows/${showId}`, {
        headers
      })
      .pipe(catchError(this.handleError));
  }

Backend Code:

Route:

func RouteShows(r *mux.Router, shows handlers.ShowHandler) {

    sub := r.PathPrefix("/api/shows").Subrouter()

    sub.HandleFunc("", getShows(shows)).Methods(http.MethodGet)
    sub.HandleFunc("/{id}", getShowById(shows)).Methods(http.MethodGet)
    sub.HandleFunc("/{id}", updateShow(shows)).Methods(http.MethodPut)
    sub.HandleFunc("", createShow(shows)).Methods(http.MethodPost)
    sub.HandleFunc("/{id}", deleteShow(shows)).Methods(http.MethodDelete)
    sub.HandleFunc("/status/{status}", getShowsByStatus(shows)).Methods(http.MethodGet)
}

API func:

func deleteShow(s handlers.ShowHandler) http.HandlerFunc {

    return func(w http.ResponseWriter, r *http.Request) {

        params := mux.Vars(r)
        var show models.Show

        if _, ok := params["id"]; !ok {
            responses.BadRequestWrapped(w, errors.New("param not found: id"))
            return
        }

        err := s.DeleteShow(params["id"])
        if err != nil {
            responses.InternalServerErrorWrapped(w, errors.FromError(err)) //TODO
            return
        }

        responses.OK(w, show)
    }

}

MongoHandler interface:

//ShowHandler handles the interface of mongo func
type ShowHandler interface {
    SearchShows(values map[string][]string, pagination *models.Pagination) ([]*models.Show, error)
    GetShows() ([]*models.Show, error)
    GetShowById(id string) (*models.Show, error)
    //GetAppointmentsCreatedByUser(username string) ([]*models.Appointment, error)
    GetShowsByStatus(status string) ([]*models.Show, error)

    CreateShow(show *models.Show) error
    UpdateShow(show *models.Show) error
    DeleteShow(id string) error
}

Mongo Handler:

//deleteShow removes a show based on Show ID from DB
func (s *shows) DeleteShow(id string) error {

    if _, err := s.mongo.DeleteOne(db_qcq, collection_shows, ValueEquals("_id", id)); err != nil {
        return err
    }

    return nil
}

Hope this is enough to give perspective.

ineedtoknow
  • 1,283
  • 5
  • 28
  • 46
  • if you google and try something you can find lots of post on this issue eg.https://stackoverflow.com/questions/7067966/why-doesnt-adding-cors-headers-to-an-options-route-allow-browsers-to-access-my – jitender Oct 18 '19 at 12:34

2 Answers2

7

I think the issue is not on the angular side, It looks NodeJs server is blocking DELETE request. You need to allow this request types on a node server.

Note - CORS: Cross-Origin Resource Sharing, that means you need to tell server from which are the valid source, and which are the valid Http method types are allowed on request. (I have added * that means all source allowed)

You can use below code (if using express)

// Initialize express middleware 
const express = require('express');
const app = express();

// Enable CORS
app.use(function (req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT,DELETE");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
    next();
});
Bhagvat Lande
  • 1,392
  • 3
  • 17
  • 34
0

Just add this below code in your headers.

const httpOptions = {
  headers: new HttpHeaders({ 
    'Access-Control-Allow-Origin':'*',
    'Authorization':'authkey',
    'userid':'1'
  })
};
upinder kumar
  • 819
  • 6
  • 8
  • Thank you for offering an answer! I tried using this but was still running into some difficulties. (I wasn't exactly sure if I was inserting in correctly.) . I'm pretty sure it was a backend issue, since after I implemented Bhagvat Lande answer I got it working. – ineedtoknow Oct 18 '19 at 13:55