Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery and $ not defined in like.js.erb returned from AJAX call

I'm using Rails 6 with bootstrap and webpack. everything was working fine. Bootstrap works, jQuery works, etc until..

I'm following this acts_as_votable tutorial: https://blog.makersacademy.com/how-to-make-a-dynamic-rails-like-unlike-button-using-the-acts-as-votable-gem-9ab71686ff82

When the PostController likes the post it goes into the like.js.erb and then in the browser returns the error

Uncaught ReferenceError: $ is not defined
  at <anonymous>:1:1
  at processResponse (rails-ujs.js:282)
  at rails-ujs.js.195
  at XMLHttpRequest.xhr.onreadystatechang (rails-ujs.js:263)

jQuery is working though as I have bootstrap working with no errors. its only when it comes in thru the ajax that it seems to be missing it.

in PostsController:

respond_to :js, :html, :json

def like
  @post = Post.find(params[:id])
  if params[:format] == 'like'
    post.liked_by current_user
  elsif params[:format] == 'unlike'
    post.unliked_by current_user
  end
end

in like.js.erb:

$('.liked-btn').on('ajax:success', function(){
  $(this).parent().parent().find('.like-count').html('<%= @post.get_likes.size %> &128591');
  $(this).closet('.liked-btn').html('Like');
});

$('.like-btn').on('ajax:success', function(){
  $(this).parent().parent().find('.like-count').html('<%= @post.get_likes.size %> &128591');
  $(this).closet('.like-btn').html('Liked');
});

The 'likes' appear to be registering its just the return ajax and javascript that errors out. The routes seem fine as per the tutorial.

One funny thing is in my controller i mistyped "respond_to" as "responds_to" and it gave the error @posts.get_likes method not known for nilClass. Which means it did not blow up on $ symbol and understood jquery just fine in that instance. so something in the controller is causing this? (never mind on the funny thing it was probably just the ERB getting processed before the javascript was being run)

Note: I also tried replacing $ with jQuery and got the same error, except with jQuery unknown at that time.

like image 245
Chris Valentine Avatar asked Jan 25 '23 15:01

Chris Valentine


1 Answers

Okay this appears to be due to the fact that even though jQuery is loaded it is not visible from the view (whatever that means honestly this isn't my area of expertise).

So my tests were showing jquery loaded, as it was. But it was only visible to webpack? I guess?

The fix is to add the following to your app/javascript/packs/application.js

import $ from 'jquery';
global.$ = jQuery;

Once this is done, the view can then see the symbol pointing to jquery.

Now my app already had the following in config/webpack/environment.js

const { environment } = require('@rails/webpacker')

const webpack = require("webpack")

environment.plugins.append("Provide", new webpack.ProvidePlugin({
    $: 'jquery',
    jQuery: 'jquery',
    Popper: ['popper.js', 'default']
}))

module.exports = environment

But apparently this is not sufficient to be seen from the view. It does however let turbolinks/bootstrap/etc work fine.

So maybe there is a better place to put the shortcut symbols where it is seen by both, but I'm not sure. As of now the entry to application.js gets it all working.

It should be noted that I did find information that "expose-loader" could help jquery be seen locally but I could not get that to work.

Referencing these posts for the fix:

  • $ is not defined when installing jQuery in Rails via Webpack
  • $ is not defined within a .js.erb view using Webpack 2 in Rails app
  • https://github.com/backpackerhh/rails4-webpack2-sample-app/pull/1

For reference I followed other sites guides on how to get bootstrap/jquery working with webpack and rails 5.2/6, but even though it does get them working. I do not see they ever confirm that jquery also works in their ajax.

Examples of the guides:

  • https://www.botreetechnologies.com/blog/introducing-jquery-in-rails-6-using-webpacker
  • https://gorails.com/forum/install-bootstrap-with-webpack-with-rails-6-beta
like image 138
Chris Valentine Avatar answered Jan 28 '23 10:01

Chris Valentine