hotwired/stimulus

Specifying default value stimulus unclear error message

zhisme opened this issue · 1 comments

When specifying values on controller, there's in console very unclear message that can waste your time debugging.

So passing the following value in controller

export default class extends Controller {
  static values = {
    turboFrameName: { type: String },
  }
}

will produce

Uncaught Error: Type "string" must match the type of the default value. Given default value: "undefined" as "undefined"

Actually I thought that those two constructions are identical
plain type and the above specified as hash

export default class extends Controller {
  static values = {
    turboFrameName: String,
  }

For me the error message looks something unclear and I don't understand what should be done (in fact it was just typo for me, I didn't know that this construction with hash options can only be used with default option)

There are 2 solutions in my opinion:

  • Adjust error message something like: Value "turboFrameName" with type "string" missing default value. Given default value: "undefined"
  • Allow both constructions to be used visa-versa, with and without default value, and specify default value only if you need one, but not throw uncaught error

Hi Zhisme,
I tried to reproduce your bug but I could not. This is what I tried and on my side it seems to be working as expected.

Let's say I have this markup:
<div data-controller="turbo-tracker"></div>

Then in my controllers, I have turbo_tracker_controller.js with the different possibilities for a string value:

import { Controller } from "@hotwired/stimulus"

export default class extends Controller {

  static values = {
    turboFrameNameA: { type: String },
    turboFrameNameB: { type: String, default: "default works" },
    turboFrameNameC: String,
  }

	connect() {
		console.log("A: ", this.turboFrameNameAValue)
		console.log("B: ", this.turboFrameNameBValue)
		console.log("C: ", this.turboFrameNameCValue)
	}
}

So it would output this:

A:
B: default works
C:

Makes sense, we don't set any value on the html, so the only value present is the default in the controller.

I tried then passing the values from the template:

<div data-controller="turbo-tracker"
	data-turbo-tracker-turbo-frame-name-a-value="A from template works"
	data-turbo-tracker-turbo-frame-name-b-value="B from template works"
	data-turbo-tracker-turbo-frame-name-c-value="C from template works"
	></div>

The results were as expected:

A: A from template works
B: B from template works
C: C from template works

I also tried passing in a number on the template:

<div data-controller="turbo-tracker"
	data-turbo-tracker-turbo-frame-name-a-value="2"
	data-turbo-tracker-turbo-frame-name-b-value="2"
	data-turbo-tracker-turbo-frame-name-c-value="2"

	></div>

Still worked as expected:
A: 2
B: 2
C: 2

Then I thought maybe if I passed the number like this:

<div data-controller="turbo-tracker"
	data-turbo-tracker-turbo-frame-name-a-value=3
	data-turbo-tracker-turbo-frame-name-b-value=3
	data-turbo-tracker-turbo-frame-name-c-value=3
	></div>

That still worked:
A: 3
B: 3
C: 3

If you could provide a full example of the bug, that would be very helpful.