Integrating an angular app in node properties, TypeError: $(...).i18n

I have built a couple of custom nodes (mostly using the default settings and not anything fancy) and i just tried the following to serve an existing compiled angular application inside the node-properties HTML. the new html looks like this.

<script type="text/html" data-template-name="Variable">
    <app-root></app-root>

    <div class="form-row">
        <label for="node-input-server"><i class="fa fa-tag"></i> InfluxDB Configuration</label>
        <input type="checkbox" id="node-input-server">
    </div>
    <div class="form-row">
        <label for="node-input-var_id"><i class="fa fa-tag"></i> Variable ID</label>
        <input type="text" id="node-input-var_id" placeholder="Inferred automatically from the selection above">
    </div>

    <div class="form-row">
        <label for="node-input-name"><i class="fa fa-tag"></i> Variable Name</label>
        <input type="text" id="node-input-name" placeholder="Inferred automatically from the selection above">
    </div>
    <div class="form-row">
        <label for="node-input-address"><i class="fa fa-tag"></i> Variable Address</label>
        <input type="text" id="node-input-address" placeholder="Inferred automatically from the selection above">
    </div>
    <div class="form-row">
        <label for="node-input-measurement"><i class="fa fa-tag"></i> Measurement</label>
        <input type="text" id="node-input-measurement" placeholder="Inferred automatically from the selection above">
    </div>
    <div class="form-row">
        <label for="node-input-valueFilter"><i class="fa fa-tag"></i> InfluxQL "Select" Function</label>
        <input type="text" id="node-input-valueFilter" placeholder="Please Refer to the Link below for any further reference">
    </div>
    <label><i>https://docs.influxdata.com/influxdb/v1.7/query_language/functions/#selectors</i></label>
    <div class="form-row">
        <label for="node-input-relativeTime"><i class="fa fa-tag"></i> Relative Time Filter</label>
        <input type="text" id="node-input-relativeTime" placeholder="Enter 0 for live measurement value or Please Refer to the Link below for any further reference">
    </div>
    <label><i>https://docs.influxdata.com/influxdb/v1.7/query_language/data_exploration/#relative-time</i></label>


    <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <script src="CLDRPluralRuleParser.js"></script>
    <script src="jquery.i18n.js"></script>
    <script src="jquery.i18n.messagestore.js"></script>
    <script src="jquery.i18n.fallbacks.js"></script>
    <script src="jquery.i18n.language.js"></script>
    <script src="jquery.i18n.parser.js"></script>
    <script src="jquery.i18n.emitter.js"></script>
    <script src="jquery.i18n.emitter.bidi.js"></script>
    <script src="ru.js"></script>
    <script src="runtime.js" defer></script><script src="polyfills.js" defer></script><script src="scripts.js" defer></script><script src="vendor.js" defer></script><script src="main.js" defer></script> -->
    <!-- <link rel="shortcut icon" href="">
    <link rel="stylesheet" href="styles.23f05eb448dfbad3c84c.css"></head>
    <script src="runtime-es2015.1eba213af0b233498d9d.js" type="module"></script>
    <script src="runtime-es5.1eba213af0b233498d9d.js" nomodule defer></script>
    <script src="polyfills-es5.da26f0600de65697c791.js" nomodule defer></script>
    <script src="polyfills-es2015.f5e187a40521b65364f1.js" type="module"></script>
    <script src="scripts.647ffdfb49656239ed30.js" defer></script>
    <script src="main-es2015.47c6fa190d218dcee470.js" type="module"></script>
    <script src="main-es5.47c6fa190d218dcee470.js" nomodule defer></script> -->
    
</script>

I edited the httpStatic inside settings.js to the location of these files.

How ever i can not get past this error while loading localhost:1880.

image

I do not think editing the red.min.js is a good idea and honestly cant understand whats written inside.

Can someone please assist me as to if such an addition of an offline angular application is even possible.

I tested this method :

  • Building an angular application
  • copyiyig all the script files to the httpStatic location
  • adding <app-root></app-root> and script refs to the template of the node.

Which worked fine with the sample/default angular app.

P.S. There are no errors while starting node-red

PS C:\Users\kib\Desktop\Node-RED Data Processor\node-red-contrib-VariableBrowser> node-red
Debugger attached.
18 Dec 18:58:59 - [info] 

Welcome to Node-RED      
===================      

18 Dec 18:58:59 - [info] Node-RED version: v1.1.3    
18 Dec 18:58:59 - [info] Node.js  version: v12.13.1  
18 Dec 18:58:59 - [info] Windows_NT 10.0.18363 x64 LE
18 Dec 18:59:00 - [info] Loading palette nodes
18 Dec 18:59:02 - [info] Dashboard version 2.23.4 started at /ui
18 Dec 18:59:02 - [info] Settings file  : \Users\kib\.node-red\settings.js
18 Dec 18:59:02 - [info] HTTP Static    : C:\Users\kib\Desktop\Node-RED Data Processor\node-red-contrib-VariableBrowser\httpStatic
18 Dec 18:59:02 - [info] Context store  : 'default' [module=memory]
18 Dec 18:59:02 - [info] User directory : \Users\kib\.node-red
18 Dec 18:59:03 - [warn] Projects disabled : editorTheme.projects.enabled=false
18 Dec 18:59:03 - [info] Flows file     : \Users\kib\.node-red\flows_nb-064.json
18 Dec 18:59:03 - [info] Server now running at http://127.0.0.1:1880/
18 Dec 18:59:03 - [warn] 

---------------------------------------------------------------------
Your flow credentials file is encrypted using a system-generated key.

If the system-generated key is lost for any reason, your credentials
file will not be recoverable, you will have to delete it and re-enter
your credentials.

You should set your own key using the 'credentialSecret' option in
your settings file. Node-RED will then re-encrypt your credentials
file using your chosen key the next time you deploy a change.
---------------------------------------------------------------------

18 Dec 18:59:03 - [info] Starting flows
18 Dec 18:59:03 - [info] Started flows
18 Dec 18:59:03 - [audit] {"event":"comms.open","level":98,"timestamp":1608314343367}
18 Dec 18:59:14 - [metric] {"level":99,"event":"runtime.memory.rss","value":64421888,"timestamp":1608314354366}

check the network tab on devtools

My betting is it cannot find your <script> resources jquery.i18n.js

Did you install jquery.i18n.js, jquery.i18n.fallbacks.js, jquery.i18n.parser.js etc into the static folder?

I suspect you need to have a leading slash on the src path e.g. <script src="/jquery.i18n.js"></script> assuming the file jquery.i18n.js is in C:\Users\kib\Desktop\Node-RED Data Processor\node-red-contrib-VariableBrowser\httpStatic

Node-RED provides its own i18n() function on $(). Installing any of those jquery i18n libraries will likely break a lot of things.

Does node-red expose the i18n to dashboard too?

Edit....

Ah - my mistake - I didn't look closely enough at the HTML. I was thrown by the mention of " httpStatic", & the thread being in the "general" category.

@Kib as Nick has pointed out, i18n is already included in node-red. For other libs, you cannot (or rather should not) be putting them in httpStatic - how would other users of your node get these?

You can create an endpoint in your node and server these files.

Search node-red source for RED.httpAdmin.post and RED.httpAdmin.get - you will find examples of how to server extra content (like the .js files) from your node src to the node-red UI

Hey, @knolleary Thanks for the assistance already. It would be great if threre is a resource on how to use it ? I went throught the internationalisation article here., but honestly couldnt understand how to solve this issue.

I kinda understood what you wrote, but I tried initially without any of those extra jquery i18n libraries, like this.

<script type="text/html" data-template-name="Variable">
    <app-root></app-root>

    <div class="form-row">
        <label for="node-input-server"><i class="fa fa-tag"></i> InfluxDB Configuration</label>
        <input type="checkbox" id="node-input-server">
    </div>
    <div class="form-row">
        <label for="node-input-var_id"><i class="fa fa-tag"></i> Variable ID</label>
        <input type="text" id="node-input-var_id" placeholder="Inferred automatically from the selection above">
    </div>

    <div class="form-row">
        <label for="node-input-name"><i class="fa fa-tag"></i> Variable Name</label>
        <input type="text" id="node-input-name" placeholder="Inferred automatically from the selection above">
    </div>
    <div class="form-row">
        <label for="node-input-address"><i class="fa fa-tag"></i> Variable Address</label>
        <input type="text" id="node-input-address" placeholder="Inferred automatically from the selection above">
    </div>
    <div class="form-row">
        <label for="node-input-measurement"><i class="fa fa-tag"></i> Measurement</label>
        <input type="text" id="node-input-measurement" placeholder="Inferred automatically from the selection above">
    </div>
    <div class="form-row">
        <label for="node-input-valueFilter"><i class="fa fa-tag"></i> InfluxQL "Select" Function</label>
        <input type="text" id="node-input-valueFilter" placeholder="Please Refer to the Link below for any further reference">
    </div>
    <label><i>https://docs.influxdata.com/influxdb/v1.7/query_language/functions/#selectors</i></label>
    <div class="form-row">
        <label for="node-input-relativeTime"><i class="fa fa-tag"></i> Relative Time Filter</label>
        <input type="text" id="node-input-relativeTime" placeholder="Enter 0 for live measurement value or Please Refer to the Link below for any further reference">
    </div>
    <label><i>https://docs.influxdata.com/influxdb/v1.7/query_language/data_exploration/#relative-time</i></label>

    <script src="runtime.js" defer></script><script src="polyfills.js" defer></script><script src="scripts.js" defer></script><script src="vendor.js" defer></script><script src="main.js" defer></script> -->
    <!-- <link rel="shortcut icon" href="">
    <link rel="stylesheet" href="styles.23f05eb448dfbad3c84c.css"></head>
    <script src="runtime-es2015.1eba213af0b233498d9d.js" type="module"></script>
    <script src="runtime-es5.1eba213af0b233498d9d.js" nomodule defer></script>
    <script src="polyfills-es5.da26f0600de65697c791.js" nomodule defer></script>
    <script src="polyfills-es2015.f5e187a40521b65364f1.js" type="module"></script>
    <script src="scripts.647ffdfb49656239ed30.js" defer></script>
    <script src="main-es2015.47c6fa190d218dcee470.js" type="module"></script>
    <script src="main-es5.47c6fa190d218dcee470.js" nomodule defer></script> -->
    
</script>

I added them as static resources to my application, only because the error popped up in the first place. Could you guide me to an article that better explains how i use the inbuilt "i18n() function on $()" or atleast make it referencable to my script and thereby my embedded angular application.

I am new to node red and started using front end stuff only a few days ago. So I would apologize if i am being dumb. :slight_smile:

Thanks @Steve-Mcl for your reply.:slight_smile:

The users of my node would be served an angular application which would need the static resource .js files , for it(embedded angular application) to be displayed in the node properties panel.

I didnt know this thanks..
I thought of adding an endpoint to the admin api (this would make my life a lot easier, honestly), but i wasnt quite sure how. Can you guide me to some article or documentation (The official NodeRED docs for the HTTP admin api doesnt state this, or i didnt read it properlöy :stuck_out_tongue: )?

also, @Steve-Mcl and @knolleary Is it possible that the Ui-Editor isnt able to find its own .i18n implementation for $() because i changed the httpStatic or is it completely unrelated ?

Well, I have no idea if the i18n() function we provide is at all similar to the one provided by jquery.i18n. Ours comes from the i18next library.

As for what you are trying to do - I don't know how practical it is to embed a whole angular app into a node's edit dialog. You'll be pulling in a lot of stuff to the page that could well cause conflicts with what's already there. Just seeing the line:

  <script src="runtime.js" defer></script><script src="polyfills.js" defer></script><script src="scripts.js" defer></script><script src="vendor.js" defer></script><script src="main.js" defer></script> 

means there's a tonne of stuff there that could be causing problems.

Depending on what you want the angular app to do, one option would be to use an iframe to embed it from a custom path you define on the RED.httpAdmin express app. But it wouldn't be able to interact with the rest of the editor dialog if that was a requirement.

Yes, I had the app inside an Iframe initially, but this,

I want this to happen, so, yeah. I am not sure as to how to proceed.

One thing that could do is pass messages through the Window.postMessage() but it would be extremely cumbersome to add listeners and pass different messages from the iframe to recognize different functions if i need to communicate between the elements of the editor dialogue.