Chris Lopez
Chris Lopez

Reputation: 301

Submit Post Form from React to Ruby on Rails API

I'm working on a school project which is to send a slogan via a form using react for the front end with Ruby on rails for the back end part. I'm using the fetch method to get this but it is really difficult to find the good values to use. I'm getting the error below... Any idea of what it could be? Thanks in advance

   /src/components/Contestform.js
SyntaxError: /Users/jennyasper/Desktop/Boulderbiketour-main/src/components/Contestform.js: Unexpected token, expected "," (42:14)

  40 |       body: JSON.stringify({
  41 | 
> 42 |         slogan[firstname]: values.first_name,
     |               ^
  43 |         slogan[lastname]: values.last_name,
  44 |         slogan[email]: values.email,
  45 |         slogan[slogan_text]: values.slogan_text,

Contestform.js :

import React , {Component}  from 'react'
import { Form , Col , InputGroup , Button, Container } from 'react-bootstrap'
import * as yup from 'yup';
import  { Formik } from 'formik'; 
import './Contestbanner.css'






const schema = yup.object({
  first_name: yup.string().required("Your first name is required"),
  last_name: yup.string().required("Your last name is required"),
  email: yup.string().required("Your email is required").email(),
  slogan_text: yup.string()
  .min(2, 'Too Short!')
  .max(50, 'Too Long!')
  .required("Your quote is required"),

 
});



class Contestform extends Component {

  async postData(values){

    try{

      let result = await fetch('http://localhost:3000/slogans', {
        method:'post', 
        mode: 'no-cors',
        headers: {
          'Accept': 'applicaton/json',
          'Content-type':'application/json'

      }, 
      body: JSON.stringify({

        slogan[firstname]: values.first_name,
        slogan[lastname]: values.last_name,
        slogan[email]: values.email,
        slogan[slogan_text]: values.slogan_text,
        
})
  }); 

  

    } catch(e){

      
      
    }
  }
  
  render(){
  return (
    <Formik
      validationSchema={schema}
      onSubmit={console.log("")}
      initialValues={{
        first_name: '',
        last_name: '',
        email: '',
        slogan_text:'',
      }}
     
    >
      {({
        handleSubmit,
        handleChange,
        handleBlur,
        values,
        touched,
        isValid,
        errors,
      }) => (
        
          
        <div className="contestbackground p-5">
        <Container >
        <Form noValidate onSubmit={handleSubmit}>
          <Form.Row>
            <Form.Group as={Col} md="4" controlId="validationFormik01">
              <Form.Label>First name</Form.Label>
              <Form.Control
                type="text"
                name="first_name"
                placeholder="First Name"
                value={values.first_name}
                onChange={handleChange}
                isInvalid={!!errors.first_name}
              />
              <Form.Control.Feedback type="invalid">{errors.first_name}</Form.Control.Feedback>
            </Form.Group>
            <Form.Group as={Col} md="4" controlId="validationFormik02">
              <Form.Label>Last name</Form.Label>
              <Form.Control
                type="text"
                name="last_name"
                placeholder="Last Name"
                value={values.last_name}
                onChange={handleChange}
                isInvalid={!!errors.last_name}
              />

              <Form.Control.Feedback type="invalid">{errors.last_name}</Form.Control.Feedback>
            </Form.Group>
            <Form.Group as={Col} md="4" controlId="validationFormikEmail">
              <Form.Label>Email</Form.Label>
              <InputGroup>
                
                <Form.Control
                  type="Email"
                  placeholder="Email"
                  aria-describedby="inputGroupPrepend"
                  name="email"
                  value={values.email}
                  onChange={handleChange}
                  isInvalid={!!errors.email}
                />
                <Form.Control.Feedback type="invalid">
                  {errors.email}
                </Form.Control.Feedback>
              </InputGroup>
            </Form.Group>
          </Form.Row>
          <Form.Row>
            <Form.Group as={Col} md="12" controlId="validationFormik03">
              <Form.Label>Slogan</Form.Label>
              <Form.Control
                type="text"
                placeholder="Slogan"
                name="slogan_text"
                value={values.slogan_text}
                onChange={handleChange}
                isInvalid={!!errors.slogan_text}
              />

              <Form.Control.Feedback type="invalid">
                {errors.slogan_text}
              </Form.Control.Feedback>
            </Form.Group>
            
          </Form.Row>
          
          <Button type="submit" className="btn-form" onClick={ () => {this.postData(values)}}>Submit your Slogan</Button>
        </Form>
        </Container>
        </div>
      )}
    </Formik>
  );

}}


export default Contestform

slogans-controller.rb:

class SlogansController < ApplicationController
  before_action :set_slogan, only: [:show, :update, :destroy]

  # GET /slogans
  def index
    @slogans = Slogan.all

    render json: @slogans
  end

  # GET /slogans/1
  def show
    render json: @slogan
  end

  # POST /slogans
  def create
    @slogan = Slogan.new(slogan_params)

    if @slogan.save
      render json: @slogan, status: :created, location: @slogan
    else
      render json: @slogan.errors, status: :unprocessable_entity
    end
  end

  # PATCH/PUT /slogans/1
  def update
    if @slogan.update(slogan_params)
      render json: @slogan
    else
      render json: @slogan.errors, status: :unprocessable_entity
    end
  end

  # DELETE /slogans/1
  def destroy
    @slogan.destroy
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_slogan
      @slogan = Slogan.find(params[:id])
    end

   # Only allow a trusted parameter "white list" through.
   def slogan_params
    params.require(:slogan).permit(:first_name, :last_name, :slogan_text, :email)
  end
end

slogan.rb :

class Slogan < ApplicationRecord
    
    validates :email , presence: true , uniqueness: true 
    validates :first_name, presence: true , length:{ minimum: 3}
    validates :last_name, presence: true , length:{ minimum: 3}
    validates :slogan_text, presence: true , length:{maximum: 50}
    
end

Upvotes: 1

Views: 825

Answers (1)

razvans
razvans

Reputation: 3251

As far as I see your strong params requires files as first_name, last_name etc..

If I were to change something I'd do it like this:

data = { slogan: values } # I see these values hold the exact fields you need.
# or
data = { slogan: { first_name: values.first_name, etc .. } } # if not 100% the same
....
async postData(values) {
  ...
  body: JSON.stringify(data)    
}

I'm currently working with https://react-hook-form.com/ for forms (I just love it, has validations and all sorts of cool things) and https://github.com/axios/axios for requests. I find these much easy to work with. If you have time you can give them a shot.

Upvotes: 1

Related Questions