truongnm
truongnm

Reputation: 2474

Rails "ajax:success" call multiple times

I'm creating a model to show user's following and follower list just like Instagram: Instagram followers list

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.

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...

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.

Upvotes: 0

Views: 751

Answers (1)

truongnm
truongnm

Reputation: 2474

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:

$(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

Upvotes: 0

Related Questions