atilla
June 11, 2019, 8:26am
1
I tried to create a post upvoting downvoting controller as in the screen below.
How can I submit the changes remotely to the model?
For example:
Every time when upvote is clicked, it should update
only vote_counter in the model
I have a simple model
rails g scaffold post titel vote_counter:integer
app/views/posts/index.html.erb
<tbody>
<% @posts.each do |post| %>
<tr data-controller="post" data-post-count="<%= post.vote_counter %>" >
<td><%= post.titel %></td>
<td>
<button data-action="post#upvote" class="button success">
Upvote
</button>
</td>
<td>
<button data-action="post#downvote" class="button alert">
Downvote
</button>
</td>
<td>
<h1 data-target="post.output"><%= post.vote_counter %></h1>
</td>
<td><%= link_to 'Show', post %></td>
<td><%= link_to 'Edit', edit_post_path(post) %></td>
<td><%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
app/javascript/controllers/post_controller.js
import { Controller } from "stimulus"
export default class extends Controller {
static targets = [ "output" ]
initialize() {
this.outputTarget.textContent = this.count
}
upvote() {
console.log('upvoting')
this.count++
}
downvote() {
this.count--
}
get count() {
return this.data.get("count")
}
set count(value) {
this.data.set("count", value)
this.outputTarget.textContent = this.count
}
}
I have a blog post that describes one way to remotely update a model:
First, I’m going to assume you’ve read the Stimulus handbook, cover to cover, like I have. Let’s say you have a Todo app, with a…
In a nutshell, the fetch() api is going to help you, and you’ll need to create a form data object that will post to your Rails controller action.
1 Like
atilla
June 11, 2019, 4:34pm
3
Hi John,
I could successfully update db using your example with a checkbox. But I have no clue how to do it without a checkbox.
The action triggered by the checkbox would become the action triggered by the buttons instead. You can calculate the count, then put that in the form you post to your rails app.
atilla
June 11, 2019, 5:19pm
5
this is what I got so far:
import { Controller } from "stimulus"
export default class extends Controller {
static targets = [ "output", "vote_counter" ]
initialize() {
this.outputTarget.textContent = this.count
}
upvote(event) {
this.count++
console.log('upvoting', this.outputTarget.textContent)
let formData = new FormData()
formData.append("post[vote_counter]", this.outputTarget.textContent);
fetch(this.data.get("update-url"), {
body: formData,
method: 'PATCH',
dataType: 'script',
credentials: "include",
headers: {
"X-CSRF-Token": getMetaValue("csrf-token")
},
}).then(function(response) {
// what do I put here
// currently I got error messages in the console
// post_controller.js:17 PATCH http://localhost:3000/posts/1 net::ERR_TOO_MANY_REDIRECTS
})
}
downvote() {
this.count--
}
get count() {
return this.data.get("count")
}
set count(value) {
this.data.set("count", value)
this.outputTarget.textContent = this.count
}
}
function getMetaValue(name) {
const element = document.head.querySelector(`meta[name="${name}"]`)
return element.getAttribute("content")
}
atilla
June 11, 2019, 5:45pm
6
I found it.
I had to put format.json { render :show, status: :ok, location: @post }
before format.html
def update
@post = Post.find_by_id params[:id]
@post.update post_params
@post.save
respond_to do |format|
if @post.update(post_params)
format.json { render :show, status: :ok, location: @post }
format.html { redirect_to @post, notice: 'Post was successfully updated.' }
1 Like