I have an app that allows users to like a post. When someone likes the post, the post request works but the view isn't updated unless I refresh the page. I'm stuck on this one. This is what I have so far:
Javascript
$('.favorite').on('click', function() {
var $heart = $(this).find('.fa');
$heart.removeClass('fa-heart-o').addClass('fa-heart');
// POST request to server to create favorite in db
$.post('/favorites', {
favorite: { post_id: $(this).attr('data-id') }
},
function(data) {
console.log(data);
});
});
The controller
def create
post = Post.find_by_id(favorite_params[:post_id])
if current_user.favorite_posts.include? post
render json: {}, status: :bad_request
else
@favorite = current_user.favorites.new(favorite_params)
if @favorite.save
render json: @favorite
else
render json: { errors: @favorite.errors.full_messages }, status: :unprocessable_entity
end
end
end
This is the view
<% if current_user.favorite_posts.include? post %>
<span class="fa fa-heart"> <%= post.favorites.count %></span>
<% else %>
<span class="fa fa-heart-o"> <%= post.favorites.count %></span>
<% end %>
Any help is appreciated. Thanks.
Do this:-
var new_count;
new_count = function() {
# your script
};
$(document).ready(new_count);
$(document).on('page:load', new_count);
This issue seems due to turbolink checkthis
There are two solutions to this:
- Invoke the view change with your in-browser ajax
- Use the Rails UJS functionality to run the view change on the server
I think your biggest problem is you don't have any functionality to change your view upon a successful request. The two options above are what you have to get it working, so I'll detail them for you here:
Ajax
Ajax will send a request for you; you still have to manage its response & functionality:
$.post('/favorites', { favorite: { post_id: $(this).attr('data-id') }},
.done( function(data) {
/* Manipulate your view here */
$("span.fa").text(data);
console.log("Success");
});
You must remember that Ajax is just an asynchronous request. That is, Javascript will act like a micro-browser, sending data to the server on your behalf.
It will then receive a response from the server (presumably containing the data you want)... it's your job to then manipulate your view with this data.
JS
The other method you could use involves the Rails UJS system. That is, you can fire javascript ERB templates after your controller action is fired.
This would give you the ability to manipulate your view as you need, without editing your current javascript:
$.post('/favorites', { favorite: { post_id: $(this).attr('data-id') }}
.done( function(data) { console.log(data); });
#app/controllers/favourites_controller.rb
class FavouritesController < ApplicationController
def create
...
respond_to do |format|
if @favorite.save
format.js #-> invokes /views/favourites/create.js.erb
format.json { render json: @favorite }
else
format.js
format.json { render json: { errors: @favorite.errors.full_messages }, status: :unprocessable_entity }
end
end
You'll then be able to use app/views/favourites/create.js.erb
to manipulate your view:
#app/views/favourites/create.js.erb
$("span.fa").hide();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With