vuetify icon indicating copy to clipboard operation
vuetify copied to clipboard

[Bug Report][3.8.6] rules composable: Uncaught TypeError: fn is not a function

Open capoaira opened this issue 6 months ago • 1 comments

Environment

Vuetify Version: 3.8.6 Last working version: 3.8.5 Vue Version: 3.5.13 Browsers: Firefox 138.0 OS: Linux x86_64

Steps to reproduce

Install with "vuetify": "=3.8.5" => localhost:3000 shows the v-text-field and validates the rule Install with "vuetify": "=3.8.6" => localhost:3000 Throws an error: Uncaught TypeError: fn is not a function

Expected Behavior

Should validate, that the input isn't empty

Actual Behavior

Throws an error: Uncaught TypeError: fn is not a function

Reproduction Link

https://github.com/capoaira/vuetify-rules-bug-report

Other comments

https://discord.com/channels/340160225338195969/1375494406366302368 The Issue is independent of OS and Browser (GniLudio from discord uses Windows with Chrome)

capoaira avatar May 23 '25 19:05 capoaira

This bug still occurs in version 3.8.8

alfianwahid avatar Jun 06 '25 05:06 alfianwahid

Is there any update on this issue? I'm following the documentation and using useRules, but now I'm unable to upgrade to Vuetify v3.9.0

hadarziv-army avatar Jul 08 '25 17:07 hadarziv-army

Seems broken for me on v3.9.0. I'm using options API, though. useRules() returns a CompRefImpl that unwraps to undefined in the template and options methods.

<script>
import { useRules } from "vuetify/labs/rules";

export default {
  data() { 
    return {
      usernameRules: [this.rules.required()]
      };
  },
  setup() {
   const rules = useRules();
   return { rules };
  },  
}
</script>

I'd make an example with play.vuetifyjs.com but I'm not sure how to register the labs plugin there.

ajslater avatar Jul 09 '25 23:07 ajslater

Docs might need an update after #21267 Here is a working example

for the playground to pick up useRules I had to make 2 changes:

  • in import-map.json
    • "vuetify/labs/rules": "https://cdn.jsdelivr.net/npm/[email protected]/lib/labs/rules/index.js",
  • and register plugin in main.js that seems to be accessible if you add and remove a file in the left sidebar

J-Sek avatar Jul 10 '25 10:07 J-Sek

Ah yes. I see.

  • The function argument to useRules() declaring the exported rules functions makes it work.
  • Rules are referenced as an array of strings, not functions.
    • Rules with arguments are referenced as arrays of strings within the rules array.
  • And this.rules becomes an implicit source of rules for the :rules attribute.

Thanks! Yeah, the docs could use an update if this is stable and the direction this labs feature will take going forward.

More complicated example with parameters

ajslater avatar Jul 10 '25 16:07 ajslater

Thanks for the helpful example @J-Sek 🙌 Just curious - is there a reason the useRules composable isn’t used the way it's shown in the documentation?

The documented approach seems to provide proper TypeScript autocompletion, while this one doesn’t.

Is there a way to keep the improved DX with autocomplete when using this pattern?

hadarziv-army avatar Jul 12 '25 12:07 hadarziv-army

laventnc found that to use built-in rules, useRules is not even required https://github.com/vuetifyjs/vuetify/issues/21552#issuecomment-2962825752 , while there is no TypeScript intellisense.

We may need an officially recommended way to use it.

kingyue737 avatar Jul 14 '25 01:07 kingyue737

Would definitely appreciate some official guidance here. I was hoping to upgrade from 3.8.1 to 3.9.3, but this breaks my app. Without any official documentation about the change, I'm not sure what the right thing to do is.

ocratravis avatar Aug 01 '25 14:08 ocratravis

@J-Sek on the latest 3.9.4 it seems there is still some discrepancies between the code and the doc.

For custom rules, the documentation mentions:

export default createRulesPlugin({
  rules: {
    aliases: {
      // Create a new rule named "pinCode"
      pinCode: err => {
        return v => (/^[\d]{4}$/.test(v)) || err || 'Field must contain a 4-digit PIN'
      },
      // Overwrite an existing rule by redefining it
      integer: err => {
        return v => Number.isInteger(v) || err || 'Field must contain an integer value'
      }
    },
  },
})

But in my IDE the function shows up like this:

export function createRulesPlugin(
    rules: RulesOptions,
    locale: LocaleInstance,
): RulesPlugin

I am also unable to reference custom rules when using the useRules() composable, but i don't know if it's because of the issue with createRulesPlugin or not.

gotson avatar Aug 06 '25 06:08 gotson

resolved by cb7cf1c

J-Sek avatar Aug 06 '25 17:08 J-Sek