FormData and Strong Params | Ruby on Rails | React

Josh Phelps
2 min readApr 11, 2020

--

Recently, I’ve been working on a capsule closet app that stores and organizes clothing items into outfits using React and a Ruby on Rails backend. I had a form that created a clothing item and I wanted a user to be able to upload an image along with other relevant information. Using Carrierwave I set up the uploader on the backend to store the file. The form was working properly on the frontend, but I ran into an issue while trying to use strong params with the form data on the backend. Since it took me a but to find a solution, I wanted to post how I was able to get it working.

This is a portion of the code on my backend for the items controller

Originally, I had the frontend POST request with content-type: ‘multipart/form-data’. However, I kept getting an an error that looked like this:

ActionController::BadRequest (Invalid request parameters: invalid %-encoding

After some trial an error, I removed the content-type and I was able to get through to the backend. Unfortunately, I still wasn’t able to use strong params and was getting this error:

ActionController::ParameterMissing (param is missing or the value is empty: item)

However, I could call params[:category] and was able to get the correct value. With this error message, I know rails wasn’t receiving a param of item or the relevant permitted parameters. I just wasn’t sure how to do that with form data.

Here’s my original frontend code building the form data:

let data = new FormData()
data.append('category', formItem.category)
data.append('sub_category', formItem.sub_category)
data.append('color', formItem.color)
data.append('brand', formItem.brand)
data.append('size', formItem.size)
data.append('avatar', formItem.image)
data.append('user_id', user.id)

I decided to try altering the names of the form data params and it worked like a charm. My updated code looked as follows:

let data = new FormData()
data.append('item[category]', formItem.category)
data.append('item[sub_category]', formItem.sub_category)
data.append('item[color]', formItem.color)
data.append('item[brand]', formItem.brand)
data.append('item[size]', formItem.size)
data.append('item[avatar]', formItem.image)
data.append('item[user_id]', user.id)

I could now call Item.new(item_params) and successfully create an item!

It’s recommended that you include a content-type in the headers for HTTP requests so I don’t necessarily recommend this approach. However, this was the best I could come up with for now. If anyone has another way of getting around this issue to include a content-type with form data then please comment.

Thanks!

--

--