Search code examples
reactjsreact-nativereact-native-fsrn-fetch-blob

How to read JSON file with React-Native-fs


I have a asset.json file with content, and need to read it within an react-native app. I already figured that it must be manually copied to the native implementation and I can verify the file is there (and readable: -rw-r--r--). Since its there and I'm using promises to obtain it, please tell me whe the output is still:

{"_40":0,"_65":0,"_55":null,"_72":null}

and not the content of the file.

const path = RNFetchBlob.fs.dirs.DocumentDir + '/' + ASSET_FILENAME;
  if (await RNFS.exists(path)){
    console.log("BLAH EXISTS");
  } else {
    console.log("BLAH DOES NOT EXIST");
  }
  const asset_content = await RNFS.readFile(path);
  console.log("local asset_content:", asset_content);
  const assets = JSON.parse(asset_content);
  console.log("local assets:", assets);

The output is:

[10:03:55] I | ReactNativeJS ▶︎ BLAH EXISTS

[10:03:55] I | ReactNativeJS ▶︎ 'local asset_content:', '{"_40":0,"_65":0,"_55":null,"_72":null}'

[10:03:55] I | ReactNativeJS ▶︎ 'local assets:', { _40: 0, _65: 0, _55: null, _72: null }

if I on the other hand use promisify for what ever reason, as suggested in some posts, the application freezes on the call to the promisified file read. Here the code with applied changes:

 const path = RNFetchBlob.fs.dirs.DocumentDir + '/' + ASSET_FILENAME;
  if (await RNFS.exists(path)){
    console.log("BLAH EXISTS");
  } else {
    console.log("BLAH DOES NOT EXIST");
  }
  const readFileAsync = promisify(RNFS.readFile);
  const asset_content = await readFileAsync(path);
  console.log("local asset_content:", asset_content);
  const assets = JSON.parse(asset_content);
  console.log("local assets:", assets);

And its output:

[10:24:16] I | ReactNativeJS ▶︎ BLAH EXISTS

The file is not big, it's only 81 lines of valid JSON. Now if I use the promise to check for any exception like this:

  const path = RNFetchBlob.fs.dirs.DocumentDir + '/' + ASSET_FILENAME;
  if (await RNFS.exists(path)){
    console.log("BLAH EXISTS");
  } else {
    console.log("BLAH DOES NOT EXIST");
  }
  const readFileAsync = promisify(RNFS.readFile);
  let asset_content = null;
  readFileAsync(path, 'utf8')
    .then((str) => {
      console.log("got result: ", str);
      asset_content = str;
    })
    .catch((e) => {
      console.log("got error:", e);
    });
  console.log("local asset_content:", asset_content);
  const assets = JSON.parse(asset_content);
  console.log("local assets:", assets);

I still have no exception and the result is null:

[10:45:00] I | ReactNativeJS ▶︎ BLAH EXISTS

[10:45:00] I | ReactNativeJS ▶︎ 'local asset_content:', null

[10:45:00] I | ReactNativeJS ▶︎ 'local assets:', null

and when I get rid of promisify and leave the promise handling, I'm back there where I started:

  const path = RNFetchBlob.fs.dirs.DocumentDir + '/' + ASSET_FILENAME;
  if (await RNFS.exists(path)){
    console.log("BLAH EXISTS");
  } else {
    console.log("BLAH DOES NOT EXIST");
  }
  let asset_content = null;
  RNFS.readFile(path, 'utf8')
    .then((str) => {
      console.log("got result: ", str);
      asset_content = str;
    })
    .catch((e) => {
      console.log("got error:", e);
    });
  console.log("local asset_content:", asset_content);
  const assets = JSON.parse(asset_content);
  console.log("local assets:", assets);

output:

[10:49:45] I | ReactNativeJS ▶︎ BLAH EXISTS

[10:49:45] I | ReactNativeJS ▶︎ 'local asset_content:', null

[10:49:45] I | ReactNativeJS ▶︎ 'local assets:', null

[10:49:45] I | ReactNativeJS ▶︎ 'got result: ', '{"_40":0,"_65":0,"_55":null,"_72":null}'

Please help. File handling is crucial to our application.

UPDATE: Here is the content of the file asset.json which is referenced with ASSET_FILE:

{
  "protobuf": [
    {
      "name": "tiny-fovapp-4c",
      "lite": false,
      "compressed": false,
      "selected": false
    },
    {
      "name": "tiny-yolo-4c-quantized",
      "lite": true,
      "compressed": true,
      "selected": false
    },
    {
      "name": "tiny-yolo-4c",
      "parentFolder": "/data/user/0/com.foviar/files/",
      "modelFilePath": "ai/protobuf/tiny-yolo-4c.pb",
      "labelsFilePath": "ai/protobuf/tiny-yolo-4c-labels.txt",
      "lite": false,
      "compressed": false,
      "selected": true
    },
    {
      "name": "tiny-yolo-4c",
      "lite": true,
      "compressed": false,
      "selected": false
    }
  ],
  "testImages": [
    {
      "name": "IMG_6924.jpg",
      "parentFolder": "/data/user/0/com.foviar/files/",
      "filePath": "ai/testimgs/IMG_6924.jpg"
    },
    {
      "name": "IMG_6924.png",
      "parentFolder": "/data/user/0/com.foviar/files/",
      "filePath": "ai/testimgs/IMG_6924.png"
    },
    {
      "name": "IMG_6929.jpg",
      "parentFolder": "/data/user/0/com.foviar/files/",
      "filePath": "ai/testimgs/IMG_6929.jpg"
    },
    {
      "name": "Part1.png",
      "parentFolder": "/data/user/0/com.foviar/files/",
      "filePath": "ai/testimgs/Part1.png"
    },
    {
      "name": "Part1_10.png",
      "parentFolder": "/data/user/0/com.foviar/files/",
      "filePath": "ai/testimgs/Part1_10.png"
    }
  ],
  "parts": [
    {
      "name": "Part1",
      "parentFolder": "/data/user/0/com.foviar/files/",
      "modelFilename": "ai/models/Part1.png",
      "drawingFilename": "ai/drawings/Part1.png",
      "annotationFilename": "ai/annotations/Part1.xml"
    },
    {
      "name": "Part2",
      "parentFolder": "/data/user/0/com.foviar/files/",
      "modelFilename": "ai/models/Part2.png",
      "drawingFilename": "ai/drawings/Part2.png",
      "annotationFilename": "ai/annotations/Part2.xml"
    },
    {
      "name": "Part3",
      "parentFolder": "/data/user/0/com.foviar/files/",
      "modelFilename": "ai/models/Part3.png",
      "drawingFilename": "ai/drawings/Part3.png",
      "annotationFilename": "ai/annotations/Part3.xml"
    }
  ]
}


Solution

  • I managed finally to copy the content of the static file into the application document directory and read and maintain it there by using NRFechtBlob.fs implementation with provided encoding param like this:

    let asset_content = null;
    try {
        await RNFetchBlob.fs.readFile(assetFile_path, 'utf8')
          .then((data) => {
            asset_content = data;
            console.log("got data: ", data);
          })
          .catch((e) => {
            console.error("got error: ", e);
          })
      } catch (err) {
        console.log('ERROR:', err);
    }
    const assets = JSON.parse(asset_content);
    

    puh. didn't thought that file handling could be such a pain in 2019.