Controller not rendering show.js.haml during AJAX - javascript

I'm making a simple AJAX call from a from_tag (search box) and want to show the results without refreshing page. The issue is that even though I can see in server console that the show action is being processed as JS, it still renders the HTML and not the js.haml file. The only way I'm getting controller to render js is by changing name to show.js . It then works as it should. show.js.erb doesn't work either. I've also tried format.js {render layout: false} without any luck. It seem to be an problem on the controller side but I might be wrong here. Any ideas appreciated!
Edit:
The controller action is working using the render "show.js.haml" option. The other issue is that escape_javascript doesn't do anything in below js.haml file.
show.js.haml
$("#main").html("#{escape_javascript(render 'artists/show', locals: {artist: #artist, updates, #updates, reach: #reach, reach_diff: #reach_diff})}");
controller
class ArtistsController < ApplicationController
def index
if params[:search]
#artist=Artist.find_by(name: params[:search])
redirect_to action: "show", id: #artist.id
else
#artists= Artist.all
end
end
def show
#artist= Artist.find(params[:id])
#updates = #artist.updates.order(created_at: :desc)
#reach = #artist.reachupdates.order(created_at: :desc)
#reach_diff= Reachupdate.last_week_diff(#artist.id)
respond_to do |format|
format.html
format.js {render "show.js.haml", layout: false}
end
end
end

You need to change render layout: false to render 'show.js.haml', layout: false
def show
#artist= Artist.find(params[:id])
#updates = #artist.updates.order(created_at: :desc)
#reach = #artist.reachupdates.order(created_at: :desc)
#reach_diff= Reachupdate.last_week_diff(#artist.id)
respond_to do |format|
format.html
format.js {render 'show.js.haml', layout: false}
end
end
Update:
The next issue I'm having is to insert ruby objects to the js file
If the file 'articles/show' is a partial file then the problem is the locals keyword should be used along with partial keyword in order to work. Try changing this
$("#main").html("#{escape_javascript(render 'artists/show', locals: {artist: #artist, updates, #updates, reach: #reach, reach_diff: #reach_diff})}");
to
$("#main").html("#{escape_javascript(render partial: 'artists/show', locals: {artist: #artist, updates, #updates, reach: #reach, reach_diff: #reach_diff})}");
Or
Just remove locals
$("#main").html("#{escape_javascript(render 'artists/show', artist: #artist, updates, #updates, reach: #reach, reach_diff: #reach_diff)}");

Related

Rails respond_to throw ActionController::UnknownFormat

So, I'm trying to respond to an action with a js file.
def my_schedule
respond_to do |format|
format.js
end
end
In my view, I have 'my_schedule.js.erb' but it's not even executed, rails broke in the controller and throw me an error : ActionController::UnknownFormat, where I have the respond_to.
I tried to add
respond_to :js, :json, :html
at the beginning of my controller out of the actions but still not working.
Need help to debug this and understand how respond_to really works.
format.js will only respond to an xhr request. You can't trigger this response by just navigating to the route that points to this controller and method.
You can test the js.erb execution by changing the respond_to block to
def my_schedule
respond_to do |format|
format.html
format.js
end
end
Then create a my_schedule.html.erb file in the same view folder as the js.erb with the following contents
<%= link_to 'Test', my_schedule_path, data: { remote: true } %>
Note that you may need to adjust that path, I'm just guessing on that.
Then navigate to the same path you were trying to before. You should see a link which, when clicked, will fire the js response.

Rails Ajax/Controller not properly updating my partial

i'm working through a tutorial to get a rails partial to display stock information using ajax. Everything is working properly and in the console I can see that the div has been updated properly, but it isn't being displayed. Here's the relevant code.
CONTROLLER
class StocksController < ApplicationController
def search
if params[:stock].present?
#stock = Stock.new_from_lookup(params[:stock])
if #stock
puts "should be working"
respond_to do |format|
format.js { render partial: 'users/result' }
end
else
puts "incorrect symbol"
flash[:danger] = "You have entered an incorrect symbol."
redirect_to my_portfolio_path
end
else
puts "nothing"
flash[:danger] = "You need to type something, what did you expect to happen?"
redirect_to my_portfolio_path
end
end
end
AJAX JS ERB
$('#results").html("<%=j (render 'users/result.html')%>")
The result of the partial is
<%if #stock%>
<div class = "well results-block">
<strong>Symbol:</strong><%= #stock.ticker%>
<strong>Name:</strong><%= #stock.name%>
<strong>Last Price:</strong><%= #stock.last_price%>
</div>
<%end%>
Let me know if there's more info you need. I'm using Rails 6.
You might want to check https://guides.rubyonrails.org/layouts_and_rendering.html#partial-layouts . You should try dropping 'partial' or add 'locals' or 'object' to render method.
all of the following render calls would all render the edit.html.erb template in the views/books directory:
render :edit
render action: :edit
render "edit"
render action: "edit"
render "books/edit"
render template: "books/edit"
You can pass an object in to this local variable via the :object option:
<%= render partial: "customer", object: #new_customer %>
In your case,
format.js { render 'users/result' }
Instead of using
$('#results").html("<%=j (render 'users/result.html')%>")
Did you try to use
document.querySelector('#results').innerHTML = '<%= j render 'users/result.html' %>'
This works fine for me.

How to render only js without html (template, layout) in Rails

I have controller Message_Controller and this Controller has method "message" in this method i wanna render .js.erb file i need call js function from rails controller.I need reneder it without html-template(layout) just only js-code in this code i will call js-function with args .How to make it ??
My routes:
post 'chat_bot/message', to: 'chat_bot#message'
My controller:
class ChatBotController < ApplicationController
layout false
def message
#gon.watch.message = params[:text]
#message = params[:text]
puts #message
render partial: 'message.js.erb', layout: false
end
end
my message.js.erb file
alert('<%=#message %>');
With
render partial: 'message.js.erb', layout: false
Rails is going to look for a partial called _message.js.erb right in the folder responding to that controller.
You can use respond_to and there specify the format and what to render:
def message
respond_to do |format|
format.html { render partial: 'message.js.erb' }
end
end
You can skip the instance variable assignation if you prefer, as you have access to the params within the request.
If your idea is to "evaluate" the alert, then it still should be inside a script tag:
<script>
alert("<%= params[:text] %>");
</script>
just update it with
def message
#message = params[:text]
respond_to do |format|
format.js
end
end

Calling JS method from Rails Controller

So this is my controller function.
def fb_close
current_user.update_user_points(SHARE_POINT_ONE, message, current_user.id, 0) if params[:post_id].present?
respond_to do |format|
format.js { render :js => "my_function();" }
end
end
and im trying to go back a js function called my_function inside script tag on the same page. I'm getting an error like ActionController::UnknownFormat
I want to know where i was wrong. Please correct me.
I have a file named fb_close.html.erb i can get the call to that file.. Is there any way i can link it with a js function
You should be better putting the code of my_function in a separate file of format js and call it like format.js { render 'your_file_name' }
respond_to do |format|
format.js { render 'your_file_name' }
end
You have to create a file like fb_close.js.erb and put the code of my_function in it and call it like this
respond_to do |format|
format.js { render 'fb_close' }
end

How do I include HTML in a JS Rails response?

I have a FooController that responds to HTML and JS (AJAX) queries:
# app/controllers/foo_controller.rb:
class FooController < ApplicationController
layout 'foo'
def bar
respond_to do |format|
format.html # foo/bar.html.erb
format.js # foo/bar.js.erb
end
end
end
The templates to support it:
# app/views/layouts/foo.html.erb:
<html>...<%= yield %>...</html>
# app/views/layouts/foo.json.erb:
<%= yield %>
And an AJAX template in which I want to render a partial:
# app/views/foo/bar.js.erb:
dojo.byID('some_div').innerHTML = "<%= escape_javascript(render(:partial => 'some/partial')) %>";
If the JS template just has plain old JS in it (like alert('hi');), it uses my JS template. When I put in the render(:partial), though, it makes the whole response use the HTML template, which means it's no longer valid JS.
A possible solution is to use a function for the layout:
class FooController < ApplicationController
layout :choose_layout
...
private
def choose_layout
return nil if request.xhr?
'foo'
end
end
But my version should work! Why doesn't it?
The most recent Railscast covers this topic (using jQuery).
I'm not quite seeing where you might be going wrong, but here's a snippit from the Railscast that works just fine to render a partial:
// views/reviews/create.js.erb
$("#new_review").before('<div id="flash_notice"><%= escape_javascript(flash.delete(:notice)) %></div>');
$("#reviews_count").html("<%= pluralize(#review.product.reviews.count, 'Review') %>");
$("#reviews").append("<%= escape_javascript(render(:partial => #review)) %>");
$("#new_review")[0].reset();
Where are you storing your Javascript? Do you have an Application.js that you're keeping things in? If so, are you including "dojo" before "application" in your javascript_include_tag?
Try the following;
class FooController < ApplicationController
layout 'foo'
def bar
respond_to do |format|
format.html
format.js { render :layout => false }
end
end
end
Hope that helps.
J.K.

Categories