Hotwire Discussion

Update part of page using turbo stream

I have an index layout page as follows:

<%= turbo_stream_from "products" %>

<div class="flex flex-col w-full">
  <div class='flex flex-row justify-between p-2'>
    <div class="">
      <h1 class='grid text-3xl font-bold'>Products</h1>
      <p class='text-sm' id="products_count"><%= @products.count %> Products</p>
    </div>
    ....

I would like to update the products_count with the current count of products in the @products instance variable. In my controller I have the following action:

def index
    @products = Product.all
    respond_to do |format|
      format.html { render :index }
      format.turbo_stream do
        render turbo_stream: turbo_stream.update(
          :products_count,
          @products.count
        )
      end
    end
  end

This works perfectly when I do an action on the page. But when I go to the /new action, create a product and redirect back to the index page. The page doesn’t reload.

Is there a way to re render the page? Here is the output from my logs:

 Started POST "/products" for 127.0.0.1 at 2021-12-23 06:55:27 +0000
 Processing by ProductsController#create as TURBO_STREAM
   Parameters: {"authenticity_token"=>"[FILTERED]", "product"=>{"name"=>"test123", "quantity"=>"4"}, "commit"=>"Create Product"}
   TRANSACTION (0.2ms)  BEGIN
   ↳ app/controllers/products_controller.rb:23:in `create'
   Product Create (1.7ms)  INSERT INTO "products" ("name", "quantity", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"  [["name", "test123"], ["quantity", 4], ["created_at", "2021-12-23 06:55:27.781391"], ["updated_at", "2021-12-23 06:55:27.781391"]]
   ↳ app/controllers/products_controller.rb:23:in `create'
   TRANSACTION (48.7ms)  COMMIT
   ↳ app/controllers/products_controller.rb:23:in `create'
   Rendered products/_product.html.erb (Duration: 1.4ms | Allocations: 262)
 [ActionCable] Broadcasting to products: "<turbo-stream action=\"append\" target=\"products\"><template>  <turbo-frame class=\"table-row\" id=\"product_40\">\n      <div class=\"table-cell border-b border-gray-100 p-4 pl-8 text-black\">\n          test123\n      </div>\n      <div class=\"table-cell border-b border-gray-100 p-4 pl-8 tex...
Redirected to http://localhost:3000/products
 Completed 302 Found in 87ms (ActiveRecord: 50.6ms | Allocations: 5085)
 Started GET "/products" for 127.0.0.1 at 2021-12-23 06:55:27 +0000
Processing by ProductsController#index as TURBO_STREAM
 Product Count (4.6ms)  SELECT COUNT(*) FROM "products"
↳ app/controllers/products_controller.rb:11:in `block (2 levels) in index'
Completed 200 OK in 11ms (Views: 0.3ms | ActiveRecord: 4.6ms | Allocations: 944)
Started GET "/cable" for 127.0.0.1 at 2021-12-23 06:55:31 +0000
Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2021-12-23 +0000
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: keep-alive, Upgrade, HTTP_UPGRADE: websocket)

By reload, you mean the products_count does not change?. If so, you need to insert this code

 <meta name="turbo-cache-control" content="no-preview">

to tell turbo to always load the current_state of the page.