How can I use a function from .js file in the oneditprepare function?

I have a function which is from a package basic-ftp which allows me to read the list of files in the specified ftp server.

I am able to successfully get the output in console of the list of files from my .js file. But I am not able to use the same function in oneditprepare function. I am not sure where I am going wrong with this.

I want to create a select tag with the names of the files in the editor of node.

This code is from the .js file.

const ftp = require("basic-ftp");
        example();
        ftpList = [];
        ftpListNames = [];

        async function example() {
          console.log("example is called");
          const client = new ftp.Client();
          client.ftp.verbose = true;
          try {
            await client.access({
              host: "192.168.104.105",
              user: "testuser",
              password: "1234",
            });
            // console.log(await client.list("/files"));
            ftpList = await client.list("/files");

            for (let i = 0; i < ftpList.length; i++) {
              ftpListNames.push(ftpList[i].name);
            }
            console.log("ftpListNames :>> ", ftpListNames);
          } catch (err) {
            console.log(err);
          }
          client.close();
        }

I am not sure how can I use the entire function in the oneditprepare .

Any help regarding this would be appreciated.

Remember that the html file runs in the front-end (browser) and the js in the back-end (server), Just because you loaded your ftp client in your js file does not mean it is available at the front end.

To link the 2 together, it is common to use an API - check out the core serial node for an example.

Please can you provide a reference link

This sounds tricky to get right... Maybe you could describe a bit more what you're trying to build? Why do you need FTP? Why do you need it in the flow editor? Do you need it in the run-time as well? Etc...

I am making a select tag in editor which should show me a list of files available in my ftp.

Why do you need that list in the flow editor? What do you do with the info. What happens in the counter-part run-time node?
I'm asking because ultimately you need to sync stuff up between editor and run-time, it's easy to get the model wrong...

So basically I am trying to run a Ansible playbook with this package node-ansible

The file which I choose from the select tag is passed as a parameter to a custom node which runs Ansible playbook.

I will have to store the selected name from the list obtained from ftp so that I can use it in runtime to call the Ansible node

Does the run-time node need to FTP? E.g., is it going to download that playbook? Or is it going to SSH somewhere to run it there?
If it needs to download the playbook you need FTP in both places (editor and run-time), if not, then you only need FTP in the editor.
You also have to decide whether the browser (where the editor runs) has FTP access or only the computer where the run-time runs...

No, the runtime node does not require FTP. It is only in the editor

Then you will want to load your FTP module into the editor only, assuming you have FTP access from the browser (which you neither confirmed nor denied...)

And you are lucky: the basic-ftp author does not publish a packaged version :roll_eyes:

Edit: see next message first, this ain't gonna work.

So, this is probably going to be a bit slow, but it should get you started.
Write your node html as a module, so start with

<script type="module">

and then import basic-ftp as follows:

import ftp from "https://esm.sh/basic-ftp@5.0.2"

and then write your code as you were going to... e.g.

RED.nodes.registerType("my ansible", {
...

Once it all works to your liking, you'll want to create a package for basic-ftp so you don't have to download it every time. You can probably add it to the package.json for your node, then install your node, then go look in the modules folder for the packaged file and then you'll have to put it into the resources subdir so you can load it into the editor and more fun stuff... Maybe someone has a better idea, though. Just check back here for help at that point. (And in the meantime wonder why Node-RED can't do proper dependencies and import for the flow editor :roll_eyes:)

Whoops, scratch that. basic-ftp is only for node.js. To run it in the browser you have to find a package that works with the browser's networking stuff...

1 Like

You don't HAVE to run that in the browser. As I've already said, the other way is to link from your .js file and provide an API. It isn't hard and the core node-red serial node contains the example that is usually referenced though plenty of other nodes also provide API's - uibuilder has quite a number.

Generally it is better to run your FTP connection from the server since the networking and security is likely to be far more reliable and comprehensible. When running from the browser, you cannot necessarily predict the networking between the client and the FTP server.

1 Like

where is the source for that? I don't have it in my installs...

Here...?

2 Likes

If I'm understanding the need correctly, you want to get a list of files from an FTP server and then display that list in a UI dialog? If so, I do this type of work using a custom backend admin API extensively. Check out my collection node-red-contrib-musiccast. In that collection, the best example is my discovery function. When a user enters an IP address of a music playback device in the config node, the UI calls an admin endpoint that does a scan of the IP to make sure it's a valid device. I start the API using the name "mcData.mcBE(RED)"

Basically, it's like this:

  • Create an admin API endpoint with the function that does the FTP call work.
  • Create a library file that includes the function which calls the backend API endpoint. This library file should be placed in the "/resources" dir. Include this file in your HTML file at the top so it's available to "oneditprepare".
  • Make sure the admin API is defined and instantiated from within the node JS file.
  • Call the function from your node HTML file. That should call the backend, which starts the FTP client, which then relays the data back to the UI for use in selectors.

If you only call the admin endpoint from only one node type, you can put the calling function in the HTML file directly to make things easier.

1 Like

Also, I just published an example node package that shows how to use an admin API to populate a list of options in the UI. I'm not going to publish it to NPM because it's not really documented or anything but feel free to download and install locally. It should be fairly easy to understand.

https://bitbucket.org/Greggulator/node-red-contrib-drinkselector/src/master/

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.