hotwired / stimulus

A modest JavaScript framework for the HTML you already have
https://stimulus.hotwired.dev/
MIT License
12.74k stars 427 forks source link

Specifying default value stimulus unclear error message #716

Open zhisme opened 1 year ago

zhisme commented 1 year ago

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:

divagueame commented 1 year ago

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.