Sourabh Banka
Sourabh Banka

Reputation: 1117

Upload image using react to active storage rails

I can sucessfully uploading image to amazon s3 bucket through postman. I am using active storage concepts. As I am buling my front-end using react so how will I store my image to react's state and will send it into params to rails backend.

Upvotes: 2

Views: 1463

Answers (1)

bwalshy
bwalshy

Reputation: 1135

I use a package called react-dropzone to take away some of the tedious parts of storing files in state, as well as uploading images from react to APIs.

Here's a very conceptual example of what you'd want to do:

import React, { Component } from "react";
import PropTypes from "prop-types";
import Dropzone from "react-dropzone";

export default class UploadImage extends Component {
  state = {
    files: []
  };

  onDrop = (files) => {
    // Get existing files from state
    // (or just the empty array if there are no files in state)
    var currentFiles = this.state.files;

    // Push file(s) from function parameters to `currentFiles` array
    const [newFiles] = files;
    currentFiles.push(newFiles);

    // Assign files dropped into component into state
    this.setState({
     files: currentFiles
    });

    // Attempt to upload the files.
    // If you want to upload after a button click, move the code
    // below to its own function and have it run after button click.
    if (files.length) {
      let formPayLoad = new FormData();

      // I'm using "avatar" here for the attribute name of the model that
      // will store the image. Change the first parameter of the 'append' function
      // below to be the name of the attribute name that fits your Rails model.
      formPayLoad.append("avatar", files[files.length - 1]);

      // Pass the data to your own defined upload function
      // that makes the call to your API. Make sure you put the
      // formPayLoad in the body of the request.
      this.props.upload(formPayLoad);
    }
  }

  render() {
    return (
      <div className="upload-image-component">
        <Dropzone
          onDrop={this.onDrop}
          multiple={true}
        >
          <p>Text that says to upload file.</p>
        </Dropzone>
      </div>
    );
  }
}

Then have your Rails controller accept the attribute that we're defining in the 'append' function in 'onDrop' above. In my example, I'm using "avatar". Another very conceptual example:

class UserController < ApiController

  # your actions

  private

  def user_params
    params.permit(
      # all your other params
      :avatar
    )
  end

end

Upvotes: 2

Related Questions