aichaos / rivescript-js

A RiveScript interpreter for JavaScript. RiveScript is a scripting language for chatterbots.
https://www.rivescript.com/
MIT License
377 stars 145 forks source link

read external json file using javascript #339

Closed giotap closed 3 years ago

giotap commented 4 years ago

Hello! I'm trying to open and read an external json file using javascript as object macro. Whatever I tried didn't work. Does anyone have any suggestion about how to make it work? Thank you!

kirsle commented 4 years ago

Hi @giotap

You can return a Promise from an object macro and then do whatever asynchronous action is needed for getting the JSON file (Fetch API; filesystem open; database query; XMLHttpRequest; etc.). Your Promise can resolve() whenever it gets the json data ready for the RiveScript response.

Example:

// example that gets a json object and
// shows output from Object.keys() listing
// the keys of the object.
+ get json keys
- <call>getJson</call>

> object getJson javascript
  return new Promise( (resolve, reject) => {
    // do anything asynchronous, here we use the web browser Fetch API
    fetch("/path/to/file.json").then( (response) => {
        let data = response.json();
        resolve( Object.keys(data) ); // or w/e
    }).catch(reject);
  });
< object
giotap commented 4 years ago

Hi @kirsle! Thank you very much for your answer.. when I am trying your example in my code, it gives me this error:

Error loading code for marco 'getJson' javax.script.ScriptException: :4:5 Expected : but found ( fetch("/resources/JsonFiles/vοcabulary-1.json").then( (response) => { ^ in at line number 4 at column number 5

kirsle commented 4 years ago

Hi @giotap

It looks like you're using the rivescript-java version of RiveScript?

I'm not sure what support the Java edition has in its JavaScript object macros. It seems by its code like it only supports synchronous JavaScript functions, so returning a Promise might not work there. @marceloverdijk may be able to chime in on this, or you can open an issue on the rivescript-java repo for this.

Fetch is a web browser API and was only an example of an asynchronous function; if using rivescript-js on the web it would work. If using rivescript-js on the server (node.js command-line application) you'd have access to built-in Node APIs like fs to read files from the filesystem -- such as fs.readFile() for async or fs.readFileSync() to open a file in a blocking, synchronous operation.

I imagine rivescript-java doesn't have Node style APIs so neither of these would be options either. If you need to use the Java edition, you might write your object macro as a Java function instead of as JavaScript and use whatever (blocking) synchronous code is needed to load your JSON file... or consider switching to use the JS version of RiveScript, which is the version you filed this issue in.