Rails “ajax:success” call multiple times
Clash Royale CLAN TAG#URR8PPP
Rails “ajax:success” call multiple times
I'm creating a model to show user's following and follower list just like Instagram:
My controller:
def create
@relationship = current_user.active_relationships.new followed_id: @user.id
if @relationship.save
byebug
respond_to :js
else
error_handle
end
end
The follow/unfollow button is a remote (ajax) form. So after it's processed, it go to create.js.erb:
$(".relationship-form").on("ajax:success", function(e, data, status, xhr)
$(this).replaceWith(
'<%= link_to "Unfollow", relationship_path(@relationship), method: :delete, data: disable_with: "Loading ...", remote: true, class: "btn btn-outline-dark common-btn btn-unfollow relationship-form" %>'
)
);
My destroy.js.erb:
$(".relationship-form").on("ajax:success", function(e, data, status, xhr)
$(this).replaceWith(
'<%= link_to "Follow", user_relationships_path(@other_user), method: :post, data: disable_with: "Loading ...", remote: true, class: "btn btn-primary common-btn btn-follow relationship-form" %>'
)
);
When I click follow user A
button the first time, it run 1 time.
user A
The problem its that if I click the follow button a second time on user B
, it run js for the last user A
and then run js for user B
(2 times). If I follow user C
, it return for user A
, user B
and user C
and so on...
user B
user A
user B
user C
user A
user B
user C
This is my button form:
<% if is_following.present? %>
<%= link_to "Unfollow", relationship_path(is_following), method: :delete, data: disable_with: "Loading ...",
remote: true, class: "btn btn-outline-dark common-btn btn-unfollow relationship-form" %>
<% else %>
<%= link_to "Follow", user_relationships_path(user), method: :post, data: disable_with: "Loading ...",
remote: true, class: "btn btn-primary common-btn btn-follow relationship-form" %>
<% end %>
Would be so nice if I could get the "clicked" element, because I can't think a way to name a unique ID for each follow and unfollow state.
add your create.js, destroy.js files also click event function too
– 7urkm3n
Aug 5 at 18:08
@xploshioOn I updated my code, please have a look
– truongnm
Aug 5 at 23:38
the problem seems to be that you are creating new events every time the user click on the element. remove the event part on the create/destroy and just replace directly the link because on that part, you are sure that it was a success, just let the line to replace the element and not the init of the event. test it and if it solve the problem, I will create the answer
– xploshioOn
Aug 5 at 23:43
That complete part needs to be inside a document ready and be loaded on the first load of that page. And it will run Everytime you send the form. Just remove it from the create/destroy js because it is not necessary to init the event more than 1 time
– xploshioOn
Aug 6 at 14:13
1 Answer
1
Turn out that I just solve it myself. Just a bit silly and dirty way.
So after controller process done, it went to js.erb file and print the result into a "display: none" div:
$("#relationship-result").html(
'<%= link_to "Unfollow", relationship_path(@relationship), method: :delete, data: disable_with: "Loading ...", remote: true, class: "btn btn-outline-dark common-btn btn-unfollow relationship-form" %>'
)
Then in application.js
, we listen for event ajax:success
on buttons we want. So by using this way, we don't get duplicate event listening, thanks @xploshioOn. Then grab the data and replace:
application.js
ajax:success
$(document).on("ajax:success", ".relationship-form", function(e, data, status, xhr)
$(this).replaceWith($("#relationship-result").html());
)
Notice that I use document
because I replace some DOM here. So a little bit trick and dirty but works :v
document
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
the problem doesn't seems to be in that part of the code, can you please add the event/ajax part?
– xploshioOn
Aug 5 at 18:01