1

Ninext : Native JavaScript

I start here a new post about the Native JavaScrip to differentiate it from the EvalJS function in which I had previously put it...

I discovered one weekago that it was possible to add comments in Ninox. In fact, this notation was originally intended to be able to add JavaScript code directly into the Ninox code. The structure of the function is there, but it was left as a skeleton.

I just added a NativeJS module in the Ninext project (see Ninext project) which gives the possibility to add JavaScript blocks in the Ninox script. As an example, this is what it looks like :

function copyToClipboard(value : text) do
    #{
    navigator.clipboard.writeText(value);
    alert( '"'+ value + '" copied on clipboard' );
    return value;
    }#
end;

copyToClipboard('User value')

Copy

Everything between #{...}# is in JavaScript, the rest is Ninox code.

I worked a little bit to make it possible to use directly Ninox variables and function parameters in the JavaScript. It is also possible to define the type of variable that return by the JavaScript code. This allows, for example, to manipulate variables of type NID (list of records) and to retrieve the value as if it had been created by a Select function.

This example takes a list of records sorted in an ascending way (the only one that is possible on Ninox) and reverses the sorting to make a descending list :

var asc := (select Customer order by 'First Name');
var desc := asc;
join(#{:nid(Customer) return desc.reverse()  }#.('First Name' + " " + 'Last Name'), " | ")

Copy

join(#{:nid(Customer) return desc.reverse()  }#.('First Name' + " " + 'Last Name'), " | ")

It is this notation at the very beginning of the JavaScript block that defines the type of value returned. Here we ask that the result be a list of entries in the Customer table.

It is important to understand that Ninox is a precompiled code that determines in advance the nature of the returned variables, whereas JavaScript is interpreted in real time and we cannot predict in advance what type of value will be returned (unlike TypeScript). To switch from one world to the other, a minimum of definition is required. 
By default, the type returned by a JavaScript block is Text.

It is also important to remember that this code only works if the Ninext project is initialized. The Ninext project is only initialized locally on the Mac application, iPhone IPad or on the local web browser. It is not initialized on the Ninox server. So if you use JavaScript blocks, you have to make sure that they will never be executed on the server, for example by API calls that would read the value of a formula (only the eval/exec function of the API can read the value of a formula).
If ever a block is executed on the server (or locally when Ninext is not initialized), the block is considered as a comment, as if it was not there.

I've attached an example database that I hope will help you get started with JavaScript block integration.

...
Since last week when I posted this text, I've made some changes in NativeJS :

- It is now possible to call a Ninox function directly from NativeJS,
- Added variable from For loop for i in select Customer do #{ var a = i['First Name']}#...
- It is now possible to have direct access to field values from a variable of Node type  (var t := this #{t.Code = ... t['User value'] = ... }#...
 - I added examples in the database
- CodeMirror is now the  interface to enter the code to with syntax highlighting (but not auto-completion for the moment)

Have fun 😄

7replies Oldest first
  • Oldest first
  • Newest first
  • Active threads
  • Popular
  • I just put a small patch online: version 1.0.3.

    I found a bug that occurred when NativeJS code called a global function. It concerned the management of variable scopes which was not respected. NativeJS tried to access variables out of scope and this caused a bug that prevents the execution of the code. This is now fixed. 

    Like
    • Sean
    • Sean
    • 1 mth ago
    • Reported - view

    Jacques TUR Hi Jacques, I downloaded your sample database and copied the code from the Run Code button to Trigger after update in User Value. It didn't run when I changed the value in that field. Do you have any plans, or is it even possible, to make it work in triggers? Thanks

    Like
    • Sean Yes, this is normal. The After update trigger code runs on the server, not locally. And on the server, Ninext does not work, it is loaded only locally. 

      This page of the documentation shows the execution contexts of some triggers and functions. We see that the triggers On new record and After update are executed on the server. Just like the select function. In these cases, the NativeJS code is simply considered as a comment.

      Like
      • Sean
      • Sean
      • 1 mth ago
      • Reported - view

      Jacques TUR Ok, but in my case I am using the Native app so that would mean it's executed on the Client according to their table. I don't know their code like you do so I'm relatively clueless to what's involved.

      Like
    • Sean It doesn't work locally either. I think I know the explanation: 

      On the web, there is a script interpreter locally and one on the server. When the script is interpreted locally, Ninext works. On the server it does not work, because it is not possible to modify the interpreter on the server.

      In the Mac application, there are also 2 interpreters: the local interpreter and the server interpreter which is in the application code. One could say that it is local, but in reality it is separated from the local code and Ninext does not have access to it. 

      It is this structure that is identical in the Mac application and on the web that allows the Mac application to work offline or connected to databases on the web.

      If you want, send me a private message to explain what you want to do. Maybe I can find a way to do it without going through After update.

      Like
      • Sean
      • Sean
      • 1 mth ago
      • Reported - view

      Jacques TUR Thank you for your time and explanation 🙏. I’m going to try a different approach and if I get stuck I will contact you.

      Like
  • Hello everyone, 

    I improved NativeJS to fix one bug with the date type return value. Now it works fine and you can get any date type like this:

    #{:date return Date.now()}# 

    return a Ninox date value : 22/11/2022 

     

    var myDate := now()
    "on "+ #{:date return myDate}# + " at " + #{:time return myDate}#
    

    return a string with date + time : on 22/11/2022 at 21:09

    NativeJS version 1.0.4

    Like 1
Like1 Follow
  • 1 Likes
  • 5 days agoLast active
  • 7Replies
  • 242Views
  • 3 Following