Home>
I want to create an image posting function with React (TypeScript), Formik, Rails API, ActiveStorage.

I'd like to create an image posting function with React (TypeScript), Formik, Rails API, ActiveStorage, but I'm having trouble with it.

ActiveSupport :: MessageVerifier :: InvalidSignature (ActiveSupport :: MessageVerifier :: InvalidSignature):


I checked what kind of data was sent to the server side

data: image/gif;base64, R0lGODlhigJVAfcAAKi7yO309RUj… ol7Gk2dhNkgZOqxEb/WIQwqVpZneO4EehDbqg8FQqAQEAOw =="


It was like this.

Corresponding source code
import React, {
  ChangeEvent,
  createRef,
} from'react'
import {makeStyles} from'@ material-ui/core/styles';
import Card from'@ material-ui/core/Card';
import CardContent from'@ material-ui/core/CardContent';
import {Field, Form, Formik} from "formik";
import {TextField} from "formik-material-ui";
import {
  Button,
  Grid,
  LinearProgress,
} from "@ material-ui/core";
import CancelTwoToneIcon from'@ material-ui/icons/CancelTwoTone';
export default function PostNewForm (props: any) {
  const classes = useStyles ();
  const [src, setSrc] = React.useState ('')
  const ref = createRef<HTMLInputElement>()
  const [state, setState] = React.useState ({{
    status: true,
  });
// Preview process
  const onClick = () =>{
    if (ref.current) {
      ref.current.click ()
    }
  }
  const onChange = (event: ChangeEvent<HTMLInputElement>, setFieldValue: any) =>{
    if (event.target.files === null) {
      return
    }
    const file = event.target.files.item (0)
    if (file === null) {
      return
    }var reader = new FileReader ()
    reader.readAsDataURL (file)
    reader.onload = () =>{
      setSrc (reader.result as string)
    }
  }
    return (
      <React.Fragment>        <Card className = {classes.root}>    <CardContent>        {src&&
          <React.Fragment>                      </React.Fragment>        }
        <Formik
            onSubmit = {async value =>{
              try {
                const post = {
                  image: src,
                  user_id: props.user.id
                }
                await
                 axios.post ('http: // localhost: 3000/api/v1/posts', {post: post}
                console.log (post);
              } catch (error) {
                alert (error.message);
              }
            }}
            render = {({submitForm, isSubmitting, isValid, setFieldValue}) =>(
            <Form>            <Grid container className = {classes.root} spacing = {2}>              {isSubmitting&&<LinearProgress />}
                <Grid item xs = {12}>                <Field
                      name = "image"
                      accept = "image"
                      type = "file"
                      onChange = {(event: ChangeEvent<HTMLInputElement>) =>onChange (event, setFieldValue)}
                      onClick = {onClick}
                    />              </Grid>              <Grid item xs = {12}>                <Button
                      type = "submit"
                      disabled = {! isValid || isSubmitting}>                    Post
                  </Button>              </Grid>            </Grid>          </Form>          )}
          />    </CardContent>        </Card>    </React.Fragment>  );
}
#post model
class Post</pre>
<pre><code data-language = "rails">def create
    post = Post.new (post_params)
    if post.save
      render json: post
    else else
      render json: post.errors
    end
  end
  private
  def post_params
    params.require (: post) .permit (: user_id,: image)
  end
What I tried
const post = {
    image: src,
 }


To

const post = {
    image: value.image,
 }


I tried it.

Supplementary information (FW/tool version, etc.)

ruby '2.6.5'
gem'rails','~>6.0.3','>= 6.0.3.2'

I would appreciate it if anyone could understand.

  • Answer # 1

    let img = new Image ();
    img.src = URL.createObjectURL (event.target.files [0]);

    Add this area to solve

Related articles