# I'm about to give up on Turbo

**URL:** <https://discuss.hotwired.dev/t/im-about-to-give-up-on-turbo/2764>\
**Category:** General\
**Created:** [April 29, 2021, 4:59pm UTC](https://discuss.hotwired.dev/t/im-about-to-give-up-on-turbo/2764 "2021-04-29T16:59:41Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![salex](https://yyz1.discourse-cdn.com/flex027/user_avatar/discuss.hotwired.dev/salex/32/658_2.png) [@salex](https://discuss.hotwired.dev/u/salex)\
**Post date:** [April 29, 2021, 4:59pm UTC](https://discuss.hotwired.dev/t/im-about-to-give-up-on-turbo/2764/1 "2021-04-29T16:59:41Z")

</div>

…at least streaming. Stimulus took a little while to get the hang of, but you had a handbook the explained just about everything - you just had to absorb it. If you look at the few Rails demos using Turbo there’s not much in the handbook that looks the same (turbo handbook is generic html - not Rails). There is also not much documentation for the hotwire-rails gem unless you can read/understand the documented code. I guess I’m not absorbing Turbo yet and I probably don’t need it - but I keep trying. I dusted off an old rails demo app I toyed with that was jQuey/coffeescript based and tried to replicate it using Turbo and a little stimulus.

- I have a simple model `Bingo` that only has a few attributes.
- The controller only has 3 actions and associated views :show, :edit, :update
- The show view is more or less a status view of the current game.
  - A board displaying what numbers have been called
  - Some stats on last and recent calls

- The edit view is almost the same as the show view but responds to clicks that trigger an update action
  - Clicking on one of the 75 numbers will add or remove that number from the calls (attribute - serialized array)
  - Clicking on a button in the button bar will trigger an update (patch form) that will change game state

My goal was to stream any changes made to the current game to anyone viewing the show view. I actually got it to semi-work trying various schemes I’ve seen in the chat demos.

```ruby
class Bingo < Game
  broadcasts
  # resource :bingo, only: [:show, :edit, :update]
end

```

```auto
// _bingo.html.slim rendered from show.html.slim
#header.w3-white MY PROBLEM
= turbo_stream_from bingo
= turbo_frame_tag dom_id(bingo) do
  #display.w3-row
    #game-status = [nil,"Resume","New","Current","current"].include?(bingo.state) ? nil : bingo.state
    - [['B',1],['I',16],['N',31],['G',46],['O',61]].each do |r|
      - c = r[0].downcase
      .square class="#{c}ltr npoint" = r[0]
      - r[1].upto(r[1] + 14) do |i|
        - id = "#{r[0]}#{i}"
        - if bingo.calls.include?(id)
          .square.num-on[id="#{id}" class="num-on#{c}"] = i
        - else
          .square.num-off[id="#{id}" class="num-off#{c}"] = i
  = render partial: 'bingos/status', locals: {bingo: bingo}

```

```auto
// _edit.html.slim rendered from edit.html.slim
= turbo_frame_tag dom_id(@bingo,:caller) do
  #display.w3-row[data-controller="callerBoard"]
    #game-status = [nil,"Resume","New","Current","current"].include?(@bingo.state) ? nil : @bingo.state
    - [['B',1],['I',16],['N',31],['G',46],['O',61]].each do |r|
      - c = r[0].downcase
      .square class="#{c}ltr npoint" = r[0]
      - r[1].upto(r[1] + 14) do |i|
        - id = "#{r[0]}#{i}"
        - if @bingo.calls.include?(id)
          .square.num-on(id="#{id}" data-callerBoard-target="toggle" data-action="click->callerBoard#clear" class="num-on#{c}") = i
        - else
          .square.num-off(id="#{id}" data-callerBoard-target="toggle" data-action="click->callerBoard#call" class="num-off#{c}") = i
    = render partial: 'status', locals: {bingo: @bingo}
    = render partial:"button_bar", locals:{bingo: @bingo}

```

The semi-works comment is that it appears to append the turbo-frame tag. The `#header.w3-white MY PROBLEM` outside the frame (added to debug) will double on every change and the html will scroll down. I’ve tried replacing the `broadcasts` in the model wih:

`broadcast_replace_to target:"bingo_#{self.id}", partial: 'bingos/bingo', locals:{bingo:self}`

on a after commit action and nothing happens. I can seen the html render in console, but the show view does not change. I also tried a couple respond\_to.turbo\_stream approaches and they also did not work.

I posted something similar a few weeks ago but was probably too vague and received zero response. Being able to stream from the model, or the controller and maybe from the turbo\_stream\_tag probably got me mixing apples and oranges. I have tried adding numerous stuff to the tags, tried what little I could find on `broadcast_tos` but the only thing that seems to semi-work is the `broadcasts`.

Any ideal what I’m not absorbing?

---

<div class="post-metadata">

**Author:** ![OutlawAndy](https://yyz1.discourse-cdn.com/flex027/user_avatar/discuss.hotwired.dev/outlawandy/32/2876_2.png) [@OutlawAndy](https://discuss.hotwired.dev/u/OutlawAndy)\
**Post date:** [April 30, 2021, 4:09pm UTC](https://discuss.hotwired.dev/t/im-about-to-give-up-on-turbo/2764/2 "2021-04-30T16:09:01Z")

</div>

I’m also struggling to wrap my head around Hotwire and agree that the handbook seems to be lacking. I haven’t personally had much time to dig in yet, but I hope that when I do there will be more resources available.

As for your specific issue, I don’t believe that steams and frames work together. Again, I don’t understand the framework either. But since no one else has chimed in yet, I’ll offer what I can…

I believe you need to swap the `turbo_frame_tag` within the `turbo_stream` for a `template`

e.g.

```auto
<turbo-stream ...>
  <template>
  ...

```

the steam is supposed to perform the chosen `action` (append, replace, etc) using the `template` like a partial.

Can anyone chime in to confirm or help lead the blind?

I’ll be interested to see if you come around on this. Good luck!

**Update**

You made me curious, so I just went and re-read the Turbo Streams section of the handbook and I think we’re coming at it from the wrong end…

You do need to use a `respond_to` block in your controller action.

I’m guessing here, but try this…

Put the game board that you want replaced in its own partial, render that partial on the main page as you normally would. Just a regular partial, no `turbo-stream` or `turbo-frame`. Just wrap the part you want replaced in a `div` with `id` of `dom_id(bingo)` or whatever your resource is. Then use something equivalent to the pseudo code below in your controller action…

basically straight out of the handbook…

```auto
respond_to do |format|
  format.turbo_stream { render turbo_stream: turbo_stream.replace(:bingo, partial: "your/bingo_partial", locals: {bingo: @bingo}) }
  format.html { redirect_to bingo_url(@bingo) }
end

```

I realize this doesn’t utilize the `broadcast` in your model. I have no knowledge of how that works, sorry.

---

<div class="post-metadata">

**Author:** ![salex](https://yyz1.discourse-cdn.com/flex027/user_avatar/discuss.hotwired.dev/salex/32/658_2.png) [@salex](https://discuss.hotwired.dev/u/salex)\
**Post date:** [May 1, 2021, 4:20pm UTC](https://discuss.hotwired.dev/t/im-about-to-give-up-on-turbo/2764/3 "2021-05-01T16:20:35Z")

</div>

Thanks for the suggestions, I’m blending them with some things I’ve discovered.

The `= turbo_stream_from bingo` is a helper method that wrap that partial in a `<template>` tag but it does not appear to have optional arguments like the tags in the handbook.

I think I’m having mixing apples with oranges problems. You can do things in the controller, model or view but with slightly different ways/syntax. I can get it broadcast to the viewer with just the stream and frame tags. It seems to default to a replace option, even if one is not called. Problem is that every update seems call a broadcast replace multiple times.

From web inspector after initial load of page

```auto
 <div class="w3-text-white">hi viewer</div>
  <turbo-cable-stream-source channel="Turbo::StreamsChannel" signed-stream-name="IloybGtPaTh2WW1sdVoyOHRaR1Z0Ynk5Q2FXNW5ieTh5Ig==--daff349a1b6f4e2a94a7cbb9323971d72e6070fa335d4e22845974887a3713ea"></turbo-cable-stream-source>
  <turbo-frame id="bingo_2"> ...

```

After two updates the will be 9 of the ` <turbo-cable-stream-source channel=...` tags before the frame tag. Another update will have 17 tags, etc, etc. Things will slow down after a few hundred!

Don’t think it should work that way so I have something wrong.

I did find a site that has some hotwire stuff on it [Noel Rappin Writes Here](https://noelrappin.com/blog/2020/12/a-brief-hello-to-hotwire-and-turbo/) he seems to take a slightly different approach/style.

Too many options, But I keep trying.

---

<div class="post-metadata">

**Author:** ![salex](https://yyz1.discourse-cdn.com/flex027/user_avatar/discuss.hotwired.dev/salex/32/658_2.png) [@salex](https://discuss.hotwired.dev/u/salex)\
**Post date:** [May 4, 2021, 4:03pm UTC](https://discuss.hotwired.dev/t/im-about-to-give-up-on-turbo/2764/7 "2021-05-04T16:03:42Z")

</div>

I figured it out and of course it was my stupid mistake.

The hotwire-rails gem is not documented very well and the _`turbo_stream_from @bingo`_ helper got me. I was curious in that it looked like a tag helper, but was not a block. I guess it wraps everything below it in a `<template>` tags.

I was getting multiple `turbo-cable-stream-source` tags:

```auto
<div id="container">
  <div class="w3-text-white" id="header">Hi Viewer</div>
  <turbo-cable-stream-source channel="Turbo::StreamsChannel" signed-stream-name="IloybGtPaTh2WW1sdVoyOHRaR1Z0Ynk5Q2FXNW5ieTh5Ig==--daff349a1b6f4e2a94a7cbb9323971d72e6070fa335d4e22845974887a3713ea"></turbo-cable-stream-source>
  <turbo-cable-stream-source channel="Turbo::StreamsChannel" signed-stream-name="IloybGtPaTh2WW1sdVoyOHRaR1Z0Ynk5Q2FXNW5ieTh5Ig==--daff349a1b6f4e2a94a7cbb9323971d72e6070fa335d4e22845974887a3713ea"></turbo-cable-stream-source>
  <turbo-cable-stream-source channel="Turbo::StreamsChannel" signed-stream-name="IloybGtPaTh2WW1sdVoyOHRaR1Z0Ynk5Q2FXNW5ieTh5Ig==--daff349a1b6f4e2a94a7cbb9323971d72e6070fa335d4e22845974887a3713ea"></turbo-cable-stream-source>
  <turbo-cable-stream-source channel="Turbo::StreamsChannel" signed-stream-name="IloybGtPaTh2WW1sdVoyOHRaR1Z0Ynk5Q2FXNW5ieTh5Ig==--daff349a1b6f4e2a94a7cbb9323971d72e6070fa335d4e22845974887a3713ea"></turbo-cable-stream-source>
  <turbo-frame id="bingo_2">
    payload html
  </turbo-frame>
</div>

```

The problem was that the _`turbo_stream_from @bingo`_ helper was in my class partial that was getting replaced. That then created multiple/duplicate streams! I simply moved it to the show page that renders the partial.

```auto
/ bingos/show.html.slim
#container
  #header.w3-text-white Hi Viewer
  = turbo_stream_from @bingo
  = render @bingo, bingo: @bingo

```

I seem to remember having these 'I really don’t understand how this works??` phase with Stimulus. Just be careful where you put that tag.

While everything works, I’m still curious on why with only `broadcasts` in the model it knew I wanted a `replace` without me having any code to tell it to replace?

---

<div class="post-metadata">

**Author:** ![salex](https://yyz1.discourse-cdn.com/flex027/user_avatar/discuss.hotwired.dev/salex/32/658_2.png) [@salex](https://discuss.hotwired.dev/u/salex)\
**Post date:** [May 6, 2021, 8:51pm UTC](https://discuss.hotwired.dev/t/im-about-to-give-up-on-turbo/2764/8 "2021-05-06T20:51:57Z")

</div>

I did put up a bare-bones example on GitHub

[turbo-bingo-demo](https://github.com/salex/turbo-bingo-demo)
