That’s what the Data Map API is for - so by extension, the Values and Classes APIs are as well. But it’s worth getting to know and understand the Data Map API to really appreciate what Values and Classes add on top of that. The Data Map API isn’t going anywhere, and in simple cases will be less verbose to use. And Data Maps are just sugar on top of native HTML data attributes.
I’ll start by demonstrating a component that is built to fetch data from a URL that’s passed in via a data property, rather than being hardcoded. Thus, different instances of the component can fetch data from different URLs.
<div data-controller="fetch" data-fetch-url="/some-url"></div>
Using Data Maps:
export default class extends Controller {
connect() {
fetchContent()
}
fetchContent() {
const url = this.data.get('url') // <-- Retrieve the data value
// ...
}
}
Using Values API:
export default class extends Controller {
static values = {
url: String
}
connect() {
fetchContent()
}
fetchContent() {
const url = this.urlValue // <-- Retrieve the data value
// ...
}
}
So in this case, the Values API is a little more code altogether, but saves a few characters in the one place that we call it. Not much to be gained in this specific example over just using Data Maps.
For now, I’d recommend starting with data maps. As you use it more and get comfortable with it, you’ll likely be able to come back and read through the Values docs and the times where it’s advantageous will become more evident. Values really are just a convenience layer over a convenience layer (Values -> Data Maps -> Data Attributes), so it’s going to be beneficial to understand data attributes and data maps first.
In the columns example, using data maps would look something like this:
<div data-controller="columns" data-columns-num="1" data-columns-url="/userPrefs">
<div>
<button data-action="columns#increase">+</button>
<button data-action="columns#decrease">-</button>
</div>
<article>My content</article>
<aside>sidebar</aside>
</div>
export default class extends Controller {
increase() {
this.data.set('num') = this.data.set('num')
const formData = new FormData()
formData.append('columns', this.data.get('num'))
fetch(this.data.get('url'), {
method: 'PUT',
body: formData
}
)
}
decrease() {
// ...
}
So in this example, the changes are being recorded to a /userPrefs URL that is passed into the controller via a data property on the controller, and the column count is being defined as a piece of data, as well. Clicking on a button grabs the column count from the data property, increases it by one, and sends that back to the server.
Note, this is not robust code - for instance, you’d want to handle a response from the server, you’d want to make sure the “num” property is an integer, etc. But it illustrates a simple example of how to grab the data, update it, and send it to the server. Also note that the sending of the data is just using vanilla JS - Stimulus just gets out of your way for most stuff and lets Javascript be the star of the show.
Hope this helps!