0

I am using Rails and I am building a page that creates new "people"(people/new). Using javascript, I scan a page with user inputs and i end up with a javascript object looking like this:

obj = { name: "John", age: 30, city: "New York" };

I want to add an event listener (keypress q) that saves this hash into the database, which looks like this:

  create_table "people", force: :cascade do |t|
    t.string "name"
    t.integer "age"
    t.string "city"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

Even though i have inputs that i scan, there IS NO form.

I know how to JSON.stringify and I know how eventListeners work but I am unsure how I can send that stringified object from javascript to ruby code that saves it to the database.

Here is the Javascript i have done so far : app/assets/javascript/testing.js

addEventListener('keyup', event => {
    if (event.key === "q") {
        var array = []
        var inputs = document.querySelectorAll("input")
        inputs.forEach ((input) => {
            array.push(input.value)
        })
        var name = array[0]
        var age = array[1]
        var city = array[2]

        var hash = {}
        hash["name"]= name
        hash["age"]= age
        hash["city"]= city
        var stringified = JSON.stringify(hash)
    }
} )

And here is what my controller looks like :

class PeopleController < ApplicationController

  def index
    @people = Person.all
  end

  def new
    @person = Person.new
  end

  def create
    Person.create(person_params)
  end

  private

  def person_params
    params.require(:person).permit(:name, :age, :city)
  end
end

What I expect is that when the "q" key is pressed, whatever is present in the inputs is saved to the database

SilentCity
  • 76
  • 10
  • 1
    Make a POST request to the backend, just as the form would do. PS: What will you do with people living in Quebec? Or people called Quinten? Since they will post non complete data while typing in their name if you tie the POST to pressing the letter Q. – Shilly Jan 14 '19 at 12:06
  • Need to submit form on keypress `$('#form_id').submit();` – Anand Jan 14 '19 at 12:10
  • @Shilly And how do you think I should do it? I cannot use the POST attribute of forms though, as I have no form, and I still have the problem that I have a stringified variable i cannot use... – SilentCity Jan 14 '19 at 12:10
  • Since you tagged the question ajax, use an ajax call. :) – Shilly Jan 14 '19 at 12:11
  • I will look into it, thx – SilentCity Jan 14 '19 at 12:13

1 Answers1

1
addEventListener('keyup', event => {
    if (event.key === "q") {
        var array = []
        var inputs = document.querySelectorAll("input")
        inputs.forEach ((input) => {
            array.push(input.value)
        })
        var name = array[0]
        var age = array[1]
        var city = array[2]

        var hash = {}
        hash["name"]= name
        hash["age"]= age
        hash["city"]= city
        var stringified = JSON.stringify(hash)

        // Using Javascript
        fetch('/people', {
           method: 'POST',
           user_params: stringified
        })
        .then((resp) => resp.json())
        .then(function (data) {
          console.log(data)
        })
        .catch(function (error) {
           console.log(error)
        })                    
    }
} )

peoples_controller.rb

  def create
    Person.create(name: params[:user_params][:name], age: params[:user_params][:name], city: params[:user_params][:city])
  end
Anand
  • 6,457
  • 3
  • 12
  • 26
  • Will only work if the OP uses JQuery. Basic xmlhttp or fetch() are the alternatives. – Shilly Jan 14 '19 at 12:15
  • @Shilly Yep Right. – Anand Jan 14 '19 at 12:15
  • @SilentCity Hi, are you using jquery ? i'm not much familiar with javascript ajax syntax :) – Anand Jan 14 '19 at 12:24
  • @Gabbar I am pretty sure I am not using JQuery – SilentCity Jan 14 '19 at 12:26
  • 1
    @SilentCity Alright, you can give try as answer is modified with javascript syntax of ajax call. – Anand Jan 14 '19 at 12:37
  • @SilentCity Here you can get ajax call using fetch https://stackoverflow.com/questions/29775797/fetch-post-json-data – Anand Jan 14 '19 at 12:43
  • Here is what the console is telling me: `Failed to load resource: the server responded with a status of 422 (Unprocessable Entity)` `SyntaxError: Unexpected token < in JSON at position 0`and the terminal : `ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):` I will look into Gabbar`s answer as well – SilentCity Jan 14 '19 at 12:44
  • 1
    @SilentCity `skip_before_filter :verify_authenticity_token , only: [:create]` use this in people controller as first line. – Anand Jan 14 '19 at 12:48
  • @Gabbar `undefined method 'skip_before_filter' for PeopleController:Class Did you mean? skip_before_action` I am using Rails 5.2.2 – SilentCity Jan 14 '19 at 12:51
  • using skip_before_action instead of skip_before_filter gives slightly different error as before `POST http://localhost:3000/people 500 (Internal Server Error)` – SilentCity Jan 14 '19 at 12:56
  • @SilentCity It should be `skip_before_action` – Anand Jan 14 '19 at 12:59
  • @Gabbar, I have tried this and got the error : `POST http://localhost:3000/people 500 (Internal Server Error)` Terminal : `NoMethodError (undefined method `[]' for nil:NilClass):` – SilentCity Jan 14 '19 at 13:00
  • `Started POST "/people" for 127.0.0.1 at 2019-01-14 13:07:40 +0100 Processing by PeopleController#create as */* Completed 500 Internal Server Error in 2ms (ActiveRecord: 0.0ms) NoMethodError (undefined method `[]' for nil:NilClass): app/controllers/people_controller.rb:16:in `create' ` – SilentCity Jan 14 '19 at 13:08
  • @SilentCity Hmm data's are not sending to controller. – Anand Jan 14 '19 at 13:13
  • I think I had a problem in the controller `params[:user_params][:age]` should be `params[:user_params[:age]]` which gives me another error `TypeError (no implicit conversion of Symbol into Integer):`so I added the `.to_i` method at the end which brings the same error message – SilentCity Jan 14 '19 at 13:17