Saving data to local files in JavaScript

Is there any method currently available which will allow me write to/create local files and subsequently read from them, particularly in JS?

Hi!

In version 0.5.3373 there are no JS APIs for this, but it’s coming very soon :slight_smile:

Awesome, thanks!

EDIT: In the meantime, I tried to make a JavaScript module in Uno that would read/write files but I’m running into some trouble. Here’s what I have so far:

FileOps.uno:

using Uno;
using Uno.Collections;
using Fuse;
using Fuse.Scripting;
using Fuse.Reactive;
using Uno.IO;

public class FileOps : Fuse.Scripting.NativeModule
{
    public FileOps()
    {
        AddMember(new NativeFunction("FileWrite", (NativeCallback)FileWrite));
        AddMember(new NativeFunction("FileRead", (NativeCallback)FileRead));
    }

    static object FileWrite(Context c, object[] args)
    {
        string filepath = args[0];
        string text = args[1];

        Uno.IO.File.WriteAllText(filepath, text);

        return null;
    }

    static object FileRead(Context c, object[] args)
    {
        string filepath = args[0];
        string text = Uno.IO.File.ReadAllText(filepath);

        return text;
    }
}

Then in the MainView.ux file:

<FileOps ux:Global='FileOps' />
<JavaScript>
  var FileWrite = require("FileOps").FileWrite;
  var FileRead = require("FileOps").FileRead;

  FileWrite("file.txt", "testing writer")
</JavaScript>

But I get this error:

D:\My Documents\PC Accessories\Programming\Javascript\Fuse Projects\TimetableUpdater\FileOps.uno(8,24): E3111: Fuse.Scripting does not contain type or namespace 'NativeModule'. Could you be missing a package reference?
D:\My Documents\PC Accessories\Programming\Javascript\Fuse Projects\TimetableUpdater\FileOps.uno(16,26): E3114: There is no identifier named 'Context' accessible in this scope. 
D:\My Documents\PC Accessories\Programming\Javascript\Fuse Projects\TimetableUpdater\FileOps.uno(26,25): E3114: There is no identifier named 'Context' accessible in this scope. 

I’m following the instructions here: https://www.fusetools.com/developers/guides/fusejs/nativemodules

Hi!

Make sure you add a reference to Fuse.Scripting and Fuse.Reactive in your project.

Hi there! Do you mean in the .uno or in the .ux? Because I think I did in the Uno file, is this right?

using Uno;
using Uno.Collections;
using Fuse;
using Fuse.Scripting;
using Fuse.Reactive;
using Uno.IO;

If you meant .ux, how would I go about doing that? Thanks!

Hi there! Do you mean in the .uno or in the .ux? Because I think I did in the Uno file, is this right?

using Uno;
using Uno.Collections;
using Fuse;
using Fuse.Scripting;
using Fuse.Reactive;
using Uno.IO;

If you meant .ux, how would I go about doing that? Thanks!

In your .unoproj

Ah I see, that fixed it. Although now I’m getting:

D:\My Documents\PC Accessories\Programming\Javascript\Fuse Projects\TimetableUpdater\FileOps.uno(12,45): E2029: '<method_group>' has no defined cast to type Fuse.Scripting.NativeCallback
D:\My Documents\PC Accessories\Programming\Javascript\Fuse Projects\TimetableUpdater\FileOps.uno(13,44): E2029: '<method_group>' has no defined cast to type Fuse.Scripting.NativeCallback

FileOps.uno:

using Uno;
using Uno.Collections;
using Fuse;
using Fuse.Scripting;
using Fuse.Reactive;
using Uno.IO;

public class FileOps : NativeModule
{
    public FileOps()
    {
        AddMember(new NativeFunction("FileWrite", (NativeCallback)FileWrite));
        AddMember(new NativeFunction("FileRead", (NativeCallback)FileRead));
    }

    static object FileWrite(Context c, string[] args)
    {
        string filepath = args[0];
        string text = args[1];

        Uno.IO.File.WriteAllText(filepath, text);

        return null;
    }

    static object FileRead(Context c, string[] args)
    {
        string filepath = args[0];
        string text = Uno.IO.File.ReadAllText(filepath);

        return text;
    }
}

Hi!

The arguments must be of type object.

static object FileRead(Context c, object[] args)
{
    string filepath = args[0] as string;

    if (filepath == null) throw new Error("FileRead(): argument must be string");

    string text = Uno.IO.File.ReadAllText(filepath);

    return text;
}

If I’m understanding right, it’s saying NativeModule is sealed?

D:\My Documents\PC Accessories\Programming\Javascript\Fuse Projects\TimetableUpdater\FileOps.uno(8,8): E4009: Cannot use a sealed class as base class

FileOps.uno:

using Uno;
using Uno.Collections;
using Fuse;
using Fuse.Scripting;
using Fuse.Reactive;
using Uno.IO;

public class FileOps : NativeModule
{
    public FileOps()
    {
        AddMember(new NativeFunction("FileWrite", (NativeCallback)FileWrite));
        AddMember(new NativeFunction("FileRead", (NativeCallback)FileRead));
    }

    static object FileWrite(Context c, object[] args)
    {
        if (args.Length != 2) throw new Error("FileWrite(): takes 2 arguments, " + args.Length.ToString() + " provided");

        string filepath = args[0] as string;
        string text = args[1] as string;

        if (filepath == null) throw new Error("FileWrite(): filepath argument must be string");
        if (text == null) throw new Error("FileWrite(): text argument must be string");

        Uno.IO.File.WriteAllText(filepath, text);

        return null;
    }

    static object FileRead(Context c, object[] args)
    {
        if (args.Length != 1) throw new Error("FileRead(): takes 1 argument, " + args.Length.ToString() + " provided");

        string filepath = args[0] as string;

        if (filepath == null) throw new Error("FileRead(): argument must be string");

        string text = Uno.IO.File.ReadAllText(filepath);

        return text;
    }
}

EDIT: Oops, didn’t mean to double-post!

Hi,

Thanks for spotting this - this is actually a bug. NativeModule was accidentally made sealed in the previous release (v0.5.3373), breaking that example.

I have fixed this now, so the next release (Monday) will include that fix + a local storage API for JS :slight_smile:

That sounds awesome, thanks again Anders!

Hi Anders, besides local storage API for JS are you considering use database engines such as mongodb or similars? Thank you

Hi Anders, we need to use NativeModule ASAP. When is fixed release coming out?

Cio, I can confirm it’s working perfectly on my end on Fuse v0.5.3524!