0

I am trying to apply AJAX on a toggle "Like" button. This setup updates the button status without refreshing the entire page, but the former <%= pluralize(@company.get_likes.size, "people liked it") %> is not removed ("0" people liked it, is added to the new "1" people liked it")

How can remove the previous "@company.get_likes.size" people liked it sentence? How can I improve the code?

controller:

  def toggle_favorite(company)
    if user_signed_in?
      if current_user.liked? company
        link_to raw("<i class='fa fa-star'></i>"), unlike_company_path(company), remote: true, method: :put
      else
        link_to raw("<i class='far fa-star'></i>"), like_company_path(company), remote: true, method: :put
      end
    else
      link_to 'sign in to like', new_user_session_path
    end
  end

route:

resources :companies do
    member do
      put "like" => "companies#like"
      put "unlike", to: "companies#unlike"
    end
end

view:

<div class="text-center">
  <div id="<%= dom_id(company) %>">
    <%= pluralize(company.get_likes.size, "people liked it")) %>
    <%= toggle_favorite(company) %>
  </div>
</div>

like.js.erb

let starIcon = document.querySelector("#company_<%= @company.id %>").querySelector('.fa-star')
starIcon.parentElement.outerHTML = "<%= pluralize(@company.get_likes.size, "people liked it") %> <%= escape_javascript(toggle_favorite(@company)) %>"

unlike.js.erb

let farstarIcon = document.querySelector("#company_<%= @company.id %>").querySelector('.fa-star')
farstarIcon.parentElement.outerHTML = " <%= pluralize(@company.get_likes.size, t('views.company.bookmark.count_bookmark')) %> <%= escape_javascript(toggle_favorite(@company)) %>"
Thierry
  • 101
  • 1
  • 10

1 Answers1

0

You can achieve this from the application_helper.rb file:

For this particular case, I'd rather use .count instead of .size (It's up to you). For more info, you can check count vs length vs size in a collection Stack Overflow question.

1- Define method:

def pluralize_get_likes(get_likes)
    if get_likes.count > 0
      "#{get_likes.count} people liked this"
    else
      "Here the text you want to be displayed (e.g.: Be the first one to vote this)"
    end
  end 

2- Apply method:

Replace "pluralize" with "pluralize_get_likes" in like.js.erb and unlike.js.erb files.

like.js.erb:

let starIcon = document.querySelector("#company_<%= @company.id %>").querySelector('.fa-star')
starIcon.parentElement.outerHTML = "<%= pluralize_get_likes(@company.get_likes) %> <%= escape_javascript(toggle_favorite(@company)) %>"

The same applies to the view:

<div class="text-center">
  <div id="<%= dom_id(company) %>">
    <%= pluralize_get_likes(company.get_likes) %>
    <%= toggle_favorite(company) %>
  </div>
</div>

That should do it.

  • Hello, thanks for the help. You are addressing the objective of code simplification (thanks for that). However, i am trying to solve the issue that the ajax call is adding the text. – Thierry Sep 24 '20 at 14:45
  • i getthe folowing error: Uncaught SyntaxError: redeclaration of let starIcon i am looking at something like: starIcon.parentElement.outerHTML.remove(); that will not trigger "Uncaught TypeError: starIcon.parentElement.outerHTML.remove is not a function" – Thierry Sep 24 '20 at 14:47
  • Hi, that error is caused by the `'let' startIcon`. Have you thought about using `like.js` and `unlike.js` files along with the `js.erb` files you already have (for the AJAX request)? Because then, you can declare and initiate a `startIcon` function in the `.js` file, and call that function method directly from the `.js.erb` file to remove the element from the DOM. I could show you how to do it. – Danger R. Gálvez Sep 25 '20 at 10:59