Fetching JSON locally

Hello so I am not understanding how to fetch a JSON file locally and display the data; I understand I need to use


var Storage = require("FuseJS/Storage");

I’m just trying to do what the different colors JSON through HTTP are doing, except I am not understanding how to do it locally. Currently the json file is colors.json and the app goes as followed:

<App Background="#eee">
    <DockPanel>
        <StatusBarBackground Dock="Top" />
        <BottomBarBackground Dock="Bottom" />
        <ScrollView>
            <Grid ColumnCount="2">
                <JavaScript>
                    var Observable = require("FuseJS/Observable");

                    var Storage = require("FuseJS/Storage");

                    var data = Observable();

                    Storage.read("color.json")
                        .then(function(contents) { 
                            data.value = contents.json(); 
                        });

                    module.exports = {
                        data: data
                    };
                </JavaScript>
                <Each Items="{data.colorsArray}">
                    <DockPanel Height="120" Margin="10,0">
                        <Panel DockPanel.Dock="Top" Margin="10" Height="30">
                            <Rectangle Layer="Background" CornerRadius="10" Fill="#fff"/>
                            <Text Value="{colorName}" TextAlignment="Center" Alignment="Center" />
                        </Panel>

                        <Rectangle Layer="Background" CornerRadius="10" Fill="{hexValue}"/>
                    </DockPanel>
                </Each>
            </Grid>
        </ScrollView>
    </DockPanel>
</App>

If someone could point in the right direction of how to observe the json file locally that would be fantastic, the documentation didn’t really help me as there isn’t much explanation for it.

And when I try writing to a text file the code isn’t working even though I have the file mytxtfile.txt listed as for where it shoud go (this part is litterally straight from the documentation) it says in the console that it wrote it successfully, but when i got to the file nothing is there.

<App>
    <JavaScript>
            var Storage = require("FuseJS/Storage");

            var success = Storage.write("mytxtfile.txt", "Hello from Fuse!");
                if(success) {
                    console.log("Successfully wrote to file");
                }
                else {
                    console.log("An error occured!");
                }

    </JavaScript>
</App>

Here is a short snippet that I use to read a file and parse JSON.

storage.read("kb.favorites.v2.txt").then(function (content)
  {
    //debug_log ('inside read favorite file');
    if (content)
    {
      //debug_log(content);
      var f = JSON.parse(content);
      //favorites.clear();
      debug_log ('favorites file read');
      //debug_log (JSON.stringify(f));
      favorites = f;
      //debug_log(JSON.stringify(favorites));

    }
  });

The docs explain it correctly, you used them wrong:

(One thing they don’t explain, but not sure if its true: I think reading for storage will only work for files you written via the Storage api, try using the bundle API)

var Bundle = require('FuseJS/Bundle');
Bundle.read('color.json')
    .then(function(contents) {
        // you should log what contents is (which should be a string, which means it doesn't have a json method)
        data.value = JSON.parse(contents); 
    });

and for writing:

var Storage = require('FuseJS/Storage');

Storage.write('mytxtfile.txt', 'Hello, from Fuse!')
    .then(function(success) {
        success // boolean
        // do your check inside here
    });

For Fuse Team Reading This: The write api should change, instead of returning a success boolean, the promise should resolve if successful returning the content back, and reject if failed returning the error.

Edwin Reynoso wrote:

The docs explain it correctly, you used them wrong:

(One thing they don’t explain, but not sure if its true: I think reading for storage will only work for files you written via the Storage api, try using the bundle API)

var Bundle = require('FuseJS/Bundle');
Bundle.read('color.json')
    .then(function(contents) {
        // you should log what contents is (which should be a string, which means it doesn't have a json method)
        data.value = JSON.parse(contents); 
    });

and for writing:

var Storage = require('FuseJS/Storage');

Storage.write('mytxtfile.txt', 'Hello, from Fuse!')
    .then(function(success) {
        success // boolean
        // do your check inside here
    });

For Fuse Team Reading This: The write api should change, instead of returning a success boolean, the promise should resolve if successful returning the content back, and reject if failed returning the error.

I’m sorry, but it seems like it didn’t want to work still; the mainview is looking like this now, and still doesn’t want to work.


<App Background="#eee">
    <DockPanel>
        <StatusBarBackground Dock="Top" />
        <BottomBarBackground Dock="Bottom" />
        <ScrollView>
            <Grid ColumnCount="2">
                <JavaScript>

                  var Observable = require("FuseJS/Observable");

                    var Storage = require("FuseJS/Storage");

                    var Bundle = require('FuseJS/Bundle');

                    var data = Observable();

                  /  Storage.read("color.json")
                        .then(function(contents) { 
                            return contents.json(); 
                        });



                     fetch('https://fuseweb.azureedge.net/forum-user-uploads/2016/08/22/pkzm4Tnk7v2s-legacy-files-ZjPdBhWNdPRMI4qK-colors.json&#39;)
                        .then(function(response) { return response.json(); })
                        .then(function(responseObject) { data.value = responseObject; });

                    /


                Bundle.read('color.json')
                    .then(function(contents) {
                        data.value = JSON.parse(contents); 
                    });



                    module.exports = {
                        data: data
                    };
                </JavaScript>
                <Each Items="{data.colorsArray}">
                    <DockPanel Height="120" Margin="10,0">
                        <Panel DockPanel.Dock="Top" Margin="10" Height="30">
                            <Rectangle Layer="Background" CornerRadius="10" Fill="#fff"/>
                            <Text Value="{colorName}" TextAlignment="Center" Alignment="Center" />
                        </Panel>

                        <Rectangle Layer="Background" CornerRadius="10" Fill="{hexValue}"/>
                    </DockPanel>
                </Each>
            </Grid>
        </ScrollView>
    </DockPanel>
</App>

I’ve never used JSON before so sorry for the invoncenience!

I am having same problem. I used Bundle. Below is my list.json file

[{
  "Director": [
    {
      "name": "Bruce Knight"
    }
  ],
  "Manager": [
    {
      "name": "Jennifer Mccoy"
    }
  ],
  "Assistance": [
    {
      "name": "Rachel Lopez"
    }
  ]
}]

JavaScript code:

     var Observable = require("FuseJS/Observable");

     var Bundle = require('FuseJS/Bundle');

      Bundle.read('list.json')
                .then(function(contents) {
                    data.value = JSON.parse(contents);
                    console.log("Reading data from file : " + data);
                }, function(error){
          console.log(error);
      });

There is no output. and yes I put “*.json:Bundle” on project

It’s pretty weird how Observables work, so for an array instead of setting the Obervable value call refreshAll

<App>
    <JavaScript>
        var Observable = require('FuseJS/Observable');
        var Bundle = require('FuseJS/Bundle');
        var Storage = require('FuseJS/Storage');

        var peopleObservable = Observable();
        Bundle.read('Assets/test.json')
            .then(function (content) {
                var people = JSON.parse(content);
                console.log('People:', people);
                peopleObservable.refreshAll(people);
            });
        module.exports = {
            peopleObservable: peopleObservable
        }
    </JavaScript>
    <StackPanel>
        <Each Items="{peopleObservable}">
            <Text Value="Name:" />
            <Text Value="{name}" />
            <Text Value="Developer:" />
            <Text Value="{isDeveloper}" />
        </Each>
    </StackPanel>
</App>

Then for a single big object set the value property:

<App>
    <JavaScript>
        var Observable = require('FuseJS/Observable');
        var Bundle = require('FuseJS/Bundle');
        var Storage = require('FuseJS/Storage');

        var peopleObservable = Observable();
        Bundle.read('Assets/test.json')
            .then(function (content) {
                var people = JSON.parse(content);
                console.log('People:', people);
                peopleObservable.value = people;
            });
        module.exports = {
            peopleObservable: peopleObservable
        }
    </JavaScript>
    <StackPanel>
        <Each Items="{peopleObservable}">
            <Text Value="Name:" />
            <Text Value="{name}" />
            <Text Value="Developer:" />
            <Text Value="{isDeveloper}" />
        </Each>
    </StackPanel>
</App>

Here’s some helper functions:

<App>
    <JavaScript>
        var Observable = require('FuseJS/Observable');
        var Bundle = require('FuseJS/Bundle');
        var Storage = require('FuseJS/Storage');

        var peopleObservable = Observable();
        var testJSON = readJSON('Assets/test.json');

        promiseJSONToObservable(testJSON, peopleObservable)
            .then(function (data) {
                // when observable value changed
            });

        function readJSON(filePath) {
            return Bundle.read(filePath)
            .then(function (content) {
                return JSON.parse(content);
            });
        }

        function promiseJSONToObservable(data, obs) {
            return data.then(function (data) {
                if(data instanceof Array) {
                    obs.refreshAll(data);
                } else {
                    obs.value = data;
                }
            });
        }

        module.exports = {
            peopleObservable: peopleObservable
        }
    </JavaScript>
    <StackPanel>
        <Each Items="{peopleObservable}">
            <Text Value="Name:" />
            <Text Value="{name}" />
            <Text Value="Developer:" />
            <Text Value="{isDeveloper}" />
        </Each>
    </StackPanel>
</App>

Now I feel like I’m overcomplicating things now, this is not straight forward, and I’m hope that I am overcomplicating things, and this should be easier, hopefully the fuse team can help here.

Hi there…

First off, thanks to Edwin for the correct answer.

This is a common confusion regarding the value property, as it actually refers to the first item of an Observable list. This makes sense for single item observables, but not so much when dealing with several items.

We’re having internal discussions on how to make this more clear.

asaxionis, Tom, Ish, does this resolve your problems?

Regarding the write method of the Storage module, we have soon-to-be-released FileSystem module that aims to replace the Storage module. The write methods of that new API rejects the promise instead of returning a boolean, as you suggested. :slight_smile: