Call a Vue function in a Stipple app

(Hi @hhaensel, asking here so others can benefit)

Given I have some function defined:

Stipple.js_methods(::MyModel) = raw"""
     badtoml () {
       this.$q.notify({
       message: 'toml file has some errors in it',
         color: 'purple'
       })
     }
"""

How can I evoke that function in my route function?

Background

A user uploads a .toml file to the app, the server checks to see if it’s formatted correctly (the user might have messed up the way they generated that file), and if the file had some errors in it, then I’d like to notify the user about it – hence the badtoml() function above.

I have the following in the dashboard:

...
p(quasar(:uploader, multiple = false, accept = ".toml", auto__upload = true, hide__upload__btn = true, label = "Upload Setup file", url = "/upload"))
...

and a route defined:

route("upload", method = POST) do
    files = Genie.Requests.filespayload()
    p = only(values(files))
    d = checksetups(String(p.data)) # here I check to see if the toml file has any issues. This returns a string with the error message or a vector with button-labels and functions.
    if d isa String # oh! the user messed it up, better let them know
        <call badtoml() some how>
    else # all good! continue with the process        
        ...
    end
end

Extra information

  • I tried using the @finish event in uploader’s API, but that 1) didn’t work, 2) would be hard to parametrize so that the message depended on if the toml file was good or not.
  • It would be cool if I could have the badtoml notification message depend on a good_toml parameter in the model.
1 Like

I have developed already a functionality that executes js code on the client. But it is still very bulky. I plan to integrate that at some point in the future.
But as a quick solution I would suggest to simply use a button or any type of input field and set its on-change property to badtoml() (@on("change", "bad_toml()").
If you don’t want to have it visible, just set the size to 0.

1 Like

So, the way I understood your suggestion is:

have some dummy input field, set its change property like this:

input("", @bind(:msg),  @on("change", "badtoml()")) # note, I tested this with `input` and got the same behavior

(keeping its size normal for debugging purposes)

and then in my uploading function, push an update to the msg parameter of my model:

< user uploaded a badly formatted toml file >
model.msg[] = "some random new string"

So if I manually input some text into that input box then badtoml() does get invoked (i.e. the notification shows). But pushing new strings into model.msg[] updates the text seen in the input box (so the change does occur), nevertheless, badtoml() doesn’t get invoked, regardless if I try it by uploading a bad toml file or push new strings into model.msg[] in the REPL.

Did I misunderstand you, or am I doing something wrong?

You understood correctly. I didn’t test it, but you could try @on("change.native", "badtoml()")

No, that didn’t work either, Maybe this is related:
https://stackoverflow.com/questions/52260011/vue-change-native-event-not-working-input-native-does

Just pushed my API change to allow for computed and watch properties
So now with the current Stipple#master you can do:

Stipple.js_watch(MyDashboard) = "name: {handler: 'badtoml'}"

See also here

2 Likes

This worked :tada: :tada: :tada:!

I’ll admit though that I do not understand how exactly js_methods, js_computed, and js_watch are supposed to be used. (A lot) more documentation and/or examples would be really useful (and might even alleviate my incessant questions).

Very exciting stuff!