I have an app that shows a different word every 10 seconds.
I have this, which works, but I’m wondering if there’s a better way:
words/show.html.erb
(which is on the /
route):
<div data-controller="words">
<turbo-frame id="word">
<div class="screen-center">
<div class="word">
<%= @word.value %>
</div>
<div class="explanation">
<%= @word.explanation %>
</div>
</div>
</turbo-frame>
</div>
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
initialize() {
setInterval(() => {
this.change()
}, 10000)
}
change() {
this.element.querySelector('turbo-frame').src = '/'
}
}
Is there maybe a better way to navigate a frame? Turbo.visit
seems to navigate the main page.
brydave
February 8, 2022, 4:55pm
#2
You could add the path to the src
attribute and reload the element with the FrameElement.reload()
function instead of programmatically setting the src attribute (Turbo Reference )? I think something like this would work, but I haven’t tested it:
<turbo-frame id="word" src="/" data-controller="words">
<div class="screen-center">
<div class="word">
<%= @word.value %>
</div>
<div class="explanation">
<%= @word.explanation %>
</div>
</div>
</turbo-frame>
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
initialize() {
setInterval(() => {
this.element.reload()
}, 10000)
}
}
Or you could see what it would look like to stream the partial from the back end every 10 seconds?
1 Like
Thanks for the suggestions.
1.
The src="/"
part doesn’t work, I get this error on the console: “Error: Matching element has a source URL which references itself”.
2.
Attaching the controller to the turbo-frame works, i.e.:
<turbo-frame id="word" data-controller="words">
this.element.src = '/'
3.
I also managed to do it with a stream:
words/show.html.erb:
<%= turbo_stream_from "main" %>
<%= render partial: 'words/word', locals: { word: @word } %>
words/_word.html.erb:
<div id="word-screen" class="screen-center">
<div class="word">
<%= word.value %>
</div>
<div class="explanation">
<%= word.explanation %>
</div>
</div>
Rails console:
(I guess I’ll need to put this in a background job)
loop do
sleep 10
Turbo::StreamsChannel.broadcast_replace_to(
'main',
target: 'word-screen',
partial: 'words/word',
locals: { word: Word.all.sample }
)
end