Search code examples
ruby-on-railsreactjsgoogle-oauthfetch

NoMethodError when trying to fetch to Rails API endpoint from React frontend


This is really leaving me scratching my head. What I'm trying to do should be pretty straight forward but for some reason I just can't get it working.

As the title says I'm trying to fetch some information from a Rails API endpoint I set up to display in a React component.

My fetch looks like this:

  componentDidMount() {
    fetch(`/api/v1/coffee_formulas`)
    .then(response => response.json())
    .then(body => {
      this.setState({ formulas: body })
    })
  }

And the API endpoint looks like:

  def index
    formulas = current_user.coffee_formulas
    render json: { status: 'SUCCESS', message: 'Loaded coffee formulas', coffee_formulas: formulas }, status: :ok
  end

The thing that is confusing me is the fact that I can navigate to http://localhost:3000/api/v1/coffee_formulas and see the exact JSON that I want to get on the React end. My assumption was that I could make a fetch to the same point but I guess I'm missing something.

A couple things to note

  • I am able to successfully post to the same API.
  • I'm using Google OmniAuth to generate a session and current_user.
  • I've tried setting the state of formulas a few different way with the same results. (ex: formulas: body.formulas, formulas: body.coffee_formulas, etc.)
  • The exact error I'm seeing in my terminal is:

NoMethodError (undefined method 'coffee_formulas' for nil:NilClass):

  • The error in my console is a 500 (Internal Server Error)

Like I said I figured this was a pretty straightforward thing but I guess I'm missing a pretty crucial detail here. Any suggestions would be very much appreciated!


Solution

  • So it ended up being a problem with the fetch its self. The controller was in fact doing what I wanted it to but the fetch needed to be formatted like:

      componentDidMount() {
      fetch(`/api/v1/coffee_formulas.json`, {
        credentials: 'same-origin',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
        },
        method: 'GET'
      }).then(response => response.json())
        .then(body => {
          this.setState({
            formulas: body.coffee_formulas,
            user: body.current_user
          })
        })
      }