I'm setting up a Rails API and cannot fetch from the console, even though I can retrieve data through the address bar. In the console, I keep getting an error:
TypeError: Failed to fetch at <anonymous>:1:1
When I make the HTTP request from the address bar, I'm am able to retrieve the data with no problem. I am using a serializer, and it is working correctly
Here is my fetch GET request:
fetch('http://localhost:3000/api/v1/users')
.then(res => res.json())
.then(data => console.log)
Here is the response:
Promise {<pending>}
[[Prototype]]: Promise
[[PromiseState]]: "rejected"
[[PromiseResult]]: TypeError: Failed to fetch at <anonymous>:1:1
Here is my index action:
def index
users = User.all
render json: UserSerializer.new(users)
end
Here are my routes:
namespace :api do
namespace :v1 do
resources :users, only: [:index, :create]
post '/login', to: 'auth#create'
get '/profile', to: 'users#profile'
end
end
Here is my serializer:
class UserSerializer
include FastJsonapi::ObjectSerializer
attributes :username, :email, :password, :role
end
When I issue the same GET request from the address bar, I get the correct response:
// 20211108121639
// http://localhost:3000/api/v1/users
{
"data": [
{
"id": "1",
"type": "user",
"attributes": {
"username": "mlgvla",
"email": "monica@test.com",
"password": null,
"role": "student"
}
}
]
}
I've tried changing the port to 3001, with exactly the same result. I have some vague memory of this weirdness happening before a long time ago, but I forgot the reason why this happens.
Thanks for any guidance and wisdom about solving this issue. Obviously, I can't set up my front-end until I know I can do a GET or POST using fetch!
That can be related to CORS security. It seems to me that you can't make a call directly to the back-end in this way. It works when you type the URL directly because it is handled by Rails
Try this gem, it should help you : RACK CORS GEM
bundle install
And then add in config/initializers/cors.rb :
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins '*'
resource '*', headers: :any, methods: [:get, :post, :patch, :put]
end
end
For more security, you should restrict origins :-)