0

I'm working through the ActionCable example within the book. All of the code is added as described and I can see the ActionCable server log hit but the updating page never updates the cost of the item. What am I missing?

The following log entry tells me that ActionCable is firing. the code is below.

  Product Load (0.1ms)  SELECT "products".* FROM "products"
  Rendered store/index.html.erb (6.0ms)
[ActionCable] Broadcasting to products: {:html=>"<p id=\"notice\"></p>\n\n<h1>Your Pragmatic Catalog</h1>\n\n\n\n      <div class=\"entry\">\n\n        <img src=\"/assets/dcbang-28758120ca6616f3f95a4b73dda112a1f8e6ac3175e35b67e78d0ab0bd177566.jpg\" alt=\"Dcbang\" />\n        <h3>Rails, Angular, Postgres, and Bootstrap</h3>\n\n        <p>\r\n      <em>Powerful, Effective, and Efficient Full-Stack Web Development</em>\r\n      As a Rails developer, you care about user experience and performance,\r\n      but you also want simple and maintainable code. Achieve all that by\r\n      embracing the full stack of web development, from styling with\r\n      Bootstrap, building an interactive user interface with AngularJS, to\r\n      storing data quickly and reliably in PostgreSQL. Take a holistic view of\r\n      full-stack development to create usable, high-performing applications,\r\n      and learn to use these technologies effectively in a Ruby on Rails\r\n      environment.\r\n      </p>\n\n        <div class=\"price_line\">\n        <span class=\"price\">$80.00</span>\n\n          <form class=\"button_to\" method=\"post\" action=\"/line_items?product_id=2\" data-remote=\"true\"><input type=\"submit\" value=\"Add to Cart\" /><input type=\"hidden\" name=\"authenticity_token\" value=\"FCedsTsN/GG6cm0VhcmY7SdGjpRzCKuuSyxKJt/Kak1Xdv/gUFVU1UYXr8n7nm2cKgvjwS23zcBorzf5P5lieg==\" /></form>\n\n        </div>\n\n      </div>\n\n\n      <div class=\"entry\">\n\n        <img src=\"/assets/7apps-f67c3d908f537bac34a290206cc1db4c6f4611196c550e49ba836b796a2602bb.jpg\" alt=\"7apps\" />\n        <h3>Seven Mobile Apps in Seven Weeks</h3>\n\n        <p>\r\n      <em>Native Apps, Multiple Platforms</em>\r\n      Answer the question “Can we build this for ALL the devices?” with a\r\n      resounding YES. This book will help you get there with a real-world\r\n      introduction to seven platforms, whether you’re new to mobile or an\r\n      experienced developer needing to expand your options. Plus, you’ll find\r\n      out which cross-platform solution makes the most sense for your needs.\r\n      </p>\n\n        <div class=\"price_line\">\n        <span class=\"price\">$26.00</span>\n\n          <form class=\"button_to\" method=\"post\" action=\"/line_items?product_id=3\" data-remote=\"true\"><input type=\"submit\" value=\"Add to Cart\" /><input type=\"hidden\" name=\"authenticity_token\" value=\"faFaDWHEcOVsP5x1x8s+A3Zd6fpFbVsW4JZzdDgpNOA+8DhcCpzYUZBaXqm5nMtyexCErxvSPXjDFQ6r2Ho81w==\" /></form>\n\n        </div>\n\n      </div>\n\n\n      <div class=\"entry\">\n\n        <img src=\"/assets/adrpo-23a974519e0d4353c6906f82b40bd4cd98b09a2ce748825370c7aa59763f5ac7.jpg\" alt=\"Adrpo\" />\n        <h3>Ruby Performance Optimization</h3>\n\n        <p>\n      <em>Why Ruby Is Slow, and How to Fix It</em>\n      You don’t have to accept slow Ruby or Rails performance. In this\n      comprehensive guide to Ruby optimization, you’ll learn how to write\n      faster Ruby code—but that’s just the beginning. See exactly what makes\n      Ruby and Rails code slow, and how to fix it. Alex Dymo will guide you\n      through perils of memory and CPU optimization, profiling, measuring,\n      performance testing, garbage collection, and tuning. You’ll find that\n      all those “hard” things aren’t so difficult after all, and your code\n      will run orders of magnitude faster.\n      </p>\n\n        <div class=\"price_line\">\n        <span class=\"price\">$46.00</span>\n\n          <form class=\"button_to\" method=\"post\" action=\"/line_items?product_id=4\" data-remote=\"true\"><input type=\"submit\" value=\"Add to Cart\" /><input type=\"hidden\" name=\"authenticity_token\" value=\"tN4iplT2QTAi9zwvn9ZXkNHwKPJouOcXz+zr0Pnytuz3j0D3P67phN6S/vPhgaLh3L1FpzYHgXnsb5YPGaG+2w==\" /></form>\n\n        </div>\n\n      </div>\n\n"}
Redirected to http://localhost:3000/products/2
Completed 302 Found in 23ms (ActiveRecord: 1.8ms)


  **#assets/javascripts/channels/products.coffee**
  App.products = App.cable.subscriptions.create "ProductsChannel",
  connected: ->
    # Called when the subscription is ready for use on the server

  disconnected: ->
    # Called when the subscription has been terminated by the server

  received: (data) ->
    # Called when there's incoming data on the websocket for this channel
  $(".store #main").html(data.html)



 **#app/views/store/index.html.erb**
    <p id="notice"><%= notice %></p>

    <h1>Your Pragmatic Catalog</h1>


    <% cache @products do %>
      <% @products.each do |product| %>
        <% cache product do %>

          <div class="entry">

            <%= image_tag(product.image_url) %>
            <h3><%= product.title %></h3>

            <%= sanitize(product.description) %>

            <div class="price_line">
            <span class="price"><%= number_to_currency(product.price) %></span>

              <%= button_to 'Add to Cart', line_items_path(product_id: product.id), remote:true %>

            </div>

          </div>

        <% end %>
      <% end %>
    <% end %>


#app/channels/products_channel.rb
class ProductsChannel < ApplicationCable::Channel
  def subscribed
    # stream_from "some_channel"
    stream_from "products"
  end

  def unsubscribed
    # Any cleanup needed when channel is unsubscribed

  end
end


#application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title>Pragprog Books Online Store</title>


    <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
    <%= csrf_meta_tags %>
  </head>

  <body class='<%= controller.controller_name %>'>

    <div id="banner">

      <%= image_tag 'logo.svg', alt: 'The Pragmatic Bookshelf' %>
      <span class="title"><%= @page_title %></span>
    </div>

    <div id="columns">
      <div id="side">

        <div id="cart">
          <% if @cart %>
              <%= hidden_div_if(@cart.line_items.empty?, id: 'cart') do %>
                <%= render @cart %>
              <% end %>
          <% end %>


        </div>

        <ul>

          <li><a href="http://www...">Home</a></li>
          <li><a href="http://www.../faq">Questions</a></li>
          <li><a href="http://www.../news">News</a></li>
          <li><a href="http://www.../contact">Contact</a></li>

        </ul>

      </div>

      <div id="main">
        <%= yield %>
      </div>
    </div>


  </body>
</html>
jvillian
  • 19,953
  • 5
  • 31
  • 44
Aaron Lind
  • 405
  • 1
  • 6
  • 16

1 Answers1

1

In your received function you are trying to access an element that doesn't seem to exist (.store #main), since you don't have an element with the class store on the code you posted.

Try and change your code to say:

  received: (data) ->
    $("#main").html(data.html)

As the #main element exists on the page.

Laith Azer
  • 589
  • 2
  • 7
  • I changed the code but no luck. The line below regarding controller translates to "store" so .store #main should be valid. . I get the same result after changing to just include #main. – Aaron Lind Dec 13 '17 at 21:06
  • I've found the issue. The products.coffee auto generated file added a comment associated with the received: (data) -> function. It consists of: # Called when there's incoming data on the websocket for this channel. If this is left in place the actual javascript generated after inspecting is mal-formed. Removing the comment completely allowed the functionality to work as originally written. Since you got me in the right direction I'll give credit. Thanks. – Aaron Lind Dec 13 '17 at 21:21