Using only native JavaScript Vanilla, Rails does not execute create.js via Ajax

Concerning Rails 4 and Vanilla JavaScript, I encountered an issue with my code for creating a Shop record via Ajax. The record is successfully created, but the create.js file is not being triggered as expected.

A strange occurrence happens in Chrome where it displays Rendered shops/create.js.erb without any action taken, while Firefox shows ActionView::MissingTemplate.

It appears that the request is being processed as HTML, which might be causing the problem.

# updated shops_controller.rb
class ShopsController < ApplicationController
  def create
    @day_id = params[:day_id]
    shop_details = JSON.parse(shop_params[:shop]).with_indifferent_access
    @shop = Shop.find_or_create_by(source_id: shop_details[:shop_id])
    @shop.save
  end

  private

  def shop_params
    params.permit(
      :shop,
      :day_id
    )
  end
end


# revised global.js
function addShop(dayId, shop) {
  var shopJSON = encodeURIComponent(JSON.stringify(shop));
  var xhr = new XMLHttpRequest();
  xhr.open("POST", "/shops", true);
  xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
  xhr.setRequestHeader("X-CSRF-Token", CSRF.token());
  xhr.send("shop=" + shopJSON + "&day_id=" + dayId);

  xhr.onreadystatechange = function () {
    if (xhr.readyState == XMLHttpRequest.DONE ) {
      if (xhr.status != 200) {
        alert('not ok');
      }
    }
  };
}

# app/views/shops/create.js.erb
alert('good');


# Updated logs for Firefox:

Started POST "/shops" for 127.0.0.1 at 2017-01-08 13:11:36 +0800
Processing by shopsController#create as HTML
  Parameters: {"shop"=>"...", "day_id"=>"85"}
  Shop Load (0.4ms)  SELECT  `shops`.* FROM `shops` WHERE `shops`.`source_id` = 'ChIJHbeh32U6K4cR-lP5hY96smc' LIMIT 1
   (0.2ms)  BEGIN
  SQL (3.6ms)  INSERT INTO `shops` (`source_id`, `created_at`, `updated_at`) VALUES ('...', '2017-01-08 05:11:36', '2017-01-08 05:11:36')
   (0.8ms)  COMMIT
   (0.2ms)  BEGIN
   (0.2ms)  COMMIT
Completed 500 Internal Server Error in 34ms (ActiveRecord: 8.1ms)

ActionView::MissingTemplate (Missing template shops/create, application/create with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder]}. Searched in:
  * "/Users/abc/Sites/powerapp/app/views"
  * "/Users/abc/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/devise-4.2.0/app/views"
):
  actionview (4.2.6) lib/action_view/path_set.rb:46:in `find'


# Revised Chrome Log:
Started POST "/shops" for 127.0.0.1 at 2017-01-08 13:13:08 +0800
Processing by shopsController#create as */*
  Parameters: {"shop"=>"...", "day_id"=>"79"}
  Shop Load (0.3ms)  SELECT  `shops`.* FROM `shops` WHERE `shops`.`source_id` = 'ChIJASFVO5VoAIkRGJbQtRWxD7w' LIMIT 1
   (0.2ms)  BEGIN
  SQL (9.2ms)  INSERT INTO `shops` (`source_id`, `created_at`, `updated_at`) VALUES ('...', '2017-01-08 05:13:08', '2017-01-08 05:13:08')
   (0.6ms)  COMMIT
   (0.2ms)  BEGIN
   (0.2ms)  COMMIT
  Rendered shops/create.js.erb (0.8ms)
Completed 200 OK in 44ms (Views: 25.1ms | ActiveRecord: 10.7ms)

Answer №1

To trigger Javascript responses like create.js.erb, update.js.erb, and destroy.js.erb, you need to use Unobtrusive JavaScript (UJS). Here's what I did to make it work:

  • Enclose everything in a form tag and include remote: true to enable UJS support
  • Use the following function to submit the form:

// Vanilla Javascript
function ujsSubmit(form) {
  var event = document.createEvent("HTMLEvents");
  event.initEvent("submit", true, false);
  form.dispatchEvent(event);
}

// jQuery
$(form).trigger("submit");

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Transform geojson data into an HTML table

As someone new to JavaScript, I am trying to figure out how to populate a HTML table with geojson entries like "ename" etc. Here is my current code: <table id="jsoncontent"></table> <script type="text/javascript"> window.onload = fu ...

The ng-click method on the checkbox input field in AngularJS is not being triggered

I'm trying to trigger a function in a toggle switch using ng-click, but the customerActiveDeactive function isn't being executed. <a title="Active/ Deactivate" > <input type="checkbox" class="js-switch" ng-init="status=True" ng-model ...

Implementing real-time updates on controls located outside of a UserControl using RadAjaxManager

Currently, I am facing an issue with a selection dialog that is being shown by a RadToolTipManager. This dialog comprises several inputs, a RadGrid, and a button enclosed within a User Control. The issue arises when the user clicks the button, as the selec ...

Text in SVG file misaligned at the edge

After creating an SVG with a base64 background image and two text areas for top and bottom texts, I encountered an issue on Internet Explorer and Edge. The problem is that the bottom text is aligned to the left instead of the center, and its position is in ...

Align the text on the same horizontal line

I have been struggling with this issue for hours. Here is my Header.js <div className="navbar-inner"> <h2>Text1</h2> <h3>Text2</h3> </div> This is the content of my Header.css: .navbar-inner { ...

Solving required packages in Express server

I am encountering difficulties with resolving dependencies on my express server. Below is the structure of my project: Calculator --dist ----app -------calculator.js -------server.js --node_modules --src ----app --------calculator.js --------server.js -- ...

create a division in the organization of the identification numbers

Is there a way to always change pages when the id changes in a foreach loop to separate the printed pages? Take a look at this code snippet: var data = [ {Id: "552", valor: "50.00", Descricao: "Fraldas", }, {Id: "552", valor: "35.00", Descrica ...

How come it's not possible to modify the text of this button right when the function kicks off?

When I click a button, it triggers a JavaScript function. The first line of code within the function uses jQuery to change the HTML of the button. However, the button's text does not update in the browser until after the entire function has completed, ...

Can you explain the functionality of isolate scope in angularjs?

I'm having trouble grasping the concept of scope : {}. Here's a snippet of code I've been working on. Why does it always display "strength" in the console instead of the actual array value? // Code goes here var app = angular.module("super ...

Debugging a node.js application remotely using SAP Cloud Foundry

Having successfully deployed multiple node.js express services on SAP Cloud Foundry, we have encountered a roadblock in the form of remote debugging. Recognizing that others may be facing similar challenges, we are putting forth a direct inquiry: What is ...

The updating of input and output does not happen instantly; there is a delay before changes

Having an issue with updating input values in React. When using the setState method, the console log does not show the updated input value immediately. For instance, typing "a n" into the input only logs "a" after the second keystroke... Although I under ...

Can the grunt command be executed automatically after saving code in TypeScript?

As a newcomer to FrontEnd and JavaScript coding in TypeScript, I find myself constantly needing to follow these steps after making a code change: save the code -> compile it using Grunt -> reload the webpage. It can be quite time-consuming. Is there a way ...

jQuery ajax errors are slipping through the cracks and not being properly addressed

I'm struggling with the jQuery ajax success handler. I've noticed that any JavaScript errors that occur within the success handler are not being reported (no errors show up in the Firefox error console). This lack of error notifications is making ...

Is it truly necessary to remove packages from devDependencies to improve performance?

It is a common understanding that packages listed under devDependencies are typically not included in the final build. So why do we remove them for the sake of performance optimization? For instance, there are discussions about replacing Moment.js with a ...

How can I increase the element by $100 using a dropdown selection in JavaScript?

Hey there! Looking to create a dropdown list with two shipping options: Special Shipping Normal Shipping <select> <option>Special Shipping</option> <option>Normal Shipping</option> </select> If the user selects Speci ...

After successfully building with Vite, an error occurs stating "TypeError: can't convert undefined to object." However, during development with Vite, everything functions flawlessly

Currently, I am utilizing Vite in conjunction with React and Typescript for my project. Interestingly, when I execute 'vite dev', the live version of the website works flawlessly without any errors showing up on the console. However, things take ...

What are the possibilities of utilizing a variable that is stated within composition to enable dynamic rendering?

I'm working on a Vue.js v3 project using the composition API. I have defined a variable in my setup like this: setup() { const showInvoiceItemForm = true; return { showInvoiceItemForm }; }, Now, I want to show a form when a button is click ...

Accessing querySelector for elements with numerical values in their name

Here is a URL snippet that I need to work with: <h1 id="header_2" title="mytitle" data-id="header_title" class="sampleclass " xpath="1">mytitle<span aria-label="sometest" class="sa ...

What approach can be taken to establish a dependency between an AngularJS controller and a value that is retrieved through ajax and loaded onto the root

I have an app that loads like this: app.js file: angular.module('App', []).run(['$rootScope', '$q', 'SessionManager', 'EndpointService', function ($rootScope, $q, SessionManager, EndpointService) { $r ...

Tips for configuring formik values

index.js const [formData, setFormData] = useState({ product_name: 'Apple', categoryId: '12345', description: 'Fresh and juicy apple', link: 'www.apple.com' }); const loadFormValues = async () => { ...