Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

variables returned from native JS methods #234

Open
dcsan opened this issue Jun 29, 2017 · 10 comments
Open

variables returned from native JS methods #234

dcsan opened this issue Jun 29, 2017 · 10 comments
Labels

Comments

@dcsan
Copy link
Contributor

dcsan commented Jun 29, 2017

I have an RS method that returns a string
and I set that string in a variable in Rivescript

But a conditional doesn't match,
even though I also print out the value of the variable to check.


  + ageask
  - how old are you?
	// - 你满18岁了吗?

  + *
  - <set agenum=<call>parseAge <star></call>>
  ^ <set agepass=<call>isLegalAge <star></call>>
  ^ {@chk}

  + chk
  * <get agepass> == no => NO!!
  * <get agepass> == yes => YES!!!
  - 你已经超过18岁了吗... [<get agepass>]?

+ dbg
  - userage: <get userage>
  ^ agenum: <get agenum>
  ^ agepass: <get agepass>
  ^ ageinfo: <get ageinfo>
  ^ hintcount: <get hintcount>
@dcsan
Copy link
Contributor Author

dcsan commented Jun 29, 2017

image

@dcsan
Copy link
Contributor Author

dcsan commented Jun 29, 2017

so this line - 你已经超过18岁了吗... [<get agepass>]?
prints out the values yes or no

but these do not match:
* <get agepass> == no => NO!!
and it always drops down to the fallthrough single line.

@dcsan
Copy link
Contributor Author

dcsan commented Jun 29, 2017

FWIW the parseAge native JS funcs are wrapped as a Promise like:

export let isLegalAge = (rs, args) => {
  let ageinfo = args[0];  // a string
  let legalCheck = TextUtils.isLegalAge(ageinfo); // 'yes' or 'no'
  return new rs.Promise( (resolve, reject) => {
    resolve(legalCheck);
  });
};

I could see if there was an issue with values not being available right away from the native JS method returns, which i saw here:
#224

However, I can run this again or call dbg again, and still not get any matching on these simple string conditional compares.

I deliberately avoid true|false type booleans, but still this can't match on yes|no strings...

I can only guess that the return from the JS native methods are actually some type of complex types that fail on RiveScript conditional compares. Are there any other examples? I tried matching with eq just for grins...

This is driving me nuts 😭 😭 😭 !

@dcsan dcsan changed the title variables returned from methods variables returned from native JS methods Jun 29, 2017
@dcsan
Copy link
Contributor Author

dcsan commented Jun 29, 2017

Digging through the issues I found this:
#201 (comment)

RiveScript.js v1.17.2 should fix the bug for synchronous object macros in redirects.

I am using v1.17.2

<set myResult=...> won't work still as that's a harder problem to solve.

So the workaround for that if we want the value immediately is to set the userVars from within the native JS method?

However, that still doesn't explain the above, as the value is showing as yes but not catching on the conditional.

@dcsan
Copy link
Contributor Author

dcsan commented Jun 29, 2017

OK yeah, so this is what I see being set in the uservars natively inside the object:

    "uservars" : {
        "agepass" : "«__call__»isLegalAge «__call_arg__»20«/__call_arg__»«/__call__»"
    }

and that just displays / parses as 20 which is very confusing for comparisons...

@kirsle
Copy link
Member

kirsle commented Jun 29, 2017

Since reading your first comment I was staring at this bit of code:

  - <set agenum=<call>parseAge <star></call>>
  ^ <set agepass=<call>isLegalAge <star></call>>

And I'm pretty sure that syntax doesn't work (well) in any version of RiveScript. The <call> tags are always handled differently from the others. In most versions of RiveScript (i.e. Python), trying to <set> based on a <call> would end up with the variable being set to "<call" and leaving a bunch of broken tag components behind in the reply. In the JS version, for the async support, the <call> tag gets mangled out really early on into those «__call__» things, and the <set> tag sets the full value of that as the variable instead (because there's no stray closing > to close the <set> tag early and break it like in the other versions).

What I think is going on is that the <set> tag successfully saved the entire placeholder text for an async object macro, so well that when a later reply tries to <get> that variable, the object macro handlers at the very end of the reply function are able to fix the macro and execute it, so you get your [yes] and [no] answers.

As for the conditional lines themselves and why they don't work by accident in the same way: if the object macros return promises, they won't work in conditionals. Some work will be needed to use Async/Await like #220 to make async macros work in conditionals.

@kirsle
Copy link
Member

kirsle commented Jun 29, 2017

What I always suggest doing instead when somebody wants to <set> the output of a <call> is to set the variable inside the macro instead of outside it, i.e. by calling rs.setUservar(rs.currentUser(), "agepass", "yes")

@kirsle kirsle added the async label Jun 29, 2017
@dcsan
Copy link
Contributor Author

dcsan commented Jul 2, 2017

I think I found another problem that setting uservars inside the macro, it seems to require another "tick" of the system for those values to be available to RS code outside the macro. ie the values are not set yet when I would call a conditional "inline".

@beltrancaliz
Copy link

beltrancaliz commented Jul 3, 2017

Related to this issue, rivescript {@} redirections do not call the javascript macros, so there is no way to modify a variable using js without some user action or that extra "tick"
Example:

! version = 2.0

> object showMsg javascript

var uid = rs.currentUser();
var msg = rs.getUservar(uid, "msg");
msg = "js modified this message";
rs.setUservar(uid, "msg", msg);


< object


+ set
- <set msg=this is a rivescript message>
^ {@call}

+ call
- <call>showMsg</call>
^ {@get}

+ get
- <get msg>

image
https://play.rivescript.com/s/uotGWF8cQY

In the above example, the js macro won't get called unless the user types "call" or "get"

@kirsle
Copy link
Member

kirsle commented Jul 5, 2017

rivescript {@} redirections do not call the javascript macros

That sounds like a bug that needs fixing. I wonder if it's calling the wrong reply function under the hood and breaking stuff wrt. object macros and promises.

Vineet107 added a commit to Vineet107/rivescript-js that referenced this issue Oct 26, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants