Expo readAsStringAsync and makeDirectoryAsync is always throwing error

I have something like below and right now it’s just causing infinite loop because the directory could not be created:

ensureDirAsync = async () => {
const props = await FileSystem.getInfoAsync(FileSystem.documentDirectory + ‘avatar’);
console.log(props)
if (props.exists && props.isDirectory) {
return props;
}

    try {
        await FileSystem.makeDirectoryAsync(FileSystem.documentDirectory + 'avatar', { intermediates: true });
    }
    catch (e) {
        console.log(e);
    }

    return await this.ensureDirAsync()
}

getAvatar = async () => {
    let dir = await this.ensureDirAsync()
    let data = null
    try {
        data = await FileSystem.readAsStringAsync(dir.uri);
    }
    catch (e) {
        console.log(e);
    }
    console.log(data)
    return data;
}

componentDidMount() {
    let avatar = this.getAvatar();

    if (avatar)
        this.setState({ avatar })
}

and also, readAsStringAsync is always giving me could not read error.

The only thing working for me right now is the moveAsync right now to save a base64 image I took using ImagePicker:

saveAvatar = async (uri) => {
await Expo.FileSystem.moveAsync({
from: uri,
to: Expo.FileSystem.documentDirectory + ‘avatar/’
})
}
_takePhoto = async () => {
const result = await ImagePicker.launchCameraAsync({
allowsEditing: false,
base64: true,
quality: 0.4
});

if (!result.cancelled) {
  this.setState({ image: result.base64 });
  this.saveAvatar(result.uri)
}

};
This is not giving me error so I assume the moving of this file is successful?
But it’s weird how this operation is successful when the directory is not even recognized to begin with…

Thanks for any pointers! :smiley:

UPDATE:
turns out the loop was my fault, so I deleted FileSystem.documentDirectory + 'avatar' file and tried running it again and the loop dissapears, then I changed the saveAvatar() to:

saveAvatar = async (uri) => {
    await Expo.FileSystem.moveAsync({
      from: uri,
      to: Expo.FileSystem.documentDirectory + 'avatar/test.jpeg'
    })
  }

but readAsStringAsync() wouldn’t give me the content of Expo.FileSystem.documentDirectory + 'avatar/' although getInfoAsync() returns this:

Object {
 "exists": 1,
 "isDirectory": true,
 "modificationTime": 1532926143,
 "size": 102,   //NOTICE THE SIZE IS WRONG AS WELL, indicating test.jpeg is not there when app is restarted
 "uri": "file:///var/mobile/Containers/Data/Application/9D3661AF-8EB5-49F5-A178-3ECA0F96BEEC/Documents/ExponentExperienceData/%2540anonymous%252FWAMS-1163fc3b-4484-44a2-9076-b4b71df1e55c/avatar/",
}

To my understanding, in this scenario readAsStringAsync should give me an array of 1 string data shouldn’t it?
UPDATE2: no it shouldn’t lol sorry guys I misread the docs

Any idea what I did wrong here?

Hi @raywinarto!

First of all, readAsStringAsync() does not accept directories as its input (FileSystem.documentDirectory + 'avatar/') is a directory. This is why:

readAsStringAsync() wouldn’t give me the content of Expo.FileSystem.documentDirectory + ‘avatar/’

Why do I know FS.docDir + avatar is a directory? Because that’s what getInfoAsync() says

getInfoAsync() returns this:

Object {
 "exists": 1,
 "isDirectory": true, // notice isDirectory == true
 "modificationTime": 1532926143,
 "size": 102,
 "uri": "file:///var/mobile/Containers/Data/Application/9D3661AF-8EB5-49F5-A178-3ECA0F96BEEC/Documents/ExponentExperienceData/%2540anonymous%252FWAMS-1163fc3b-4484-44a2-9076-b4b71df1e55c/avatar/",
}

If you want to read what files are in a directory, use FileSystem.readDirectoryAsync. :slightly_smiling_face:

If you’d like to save the avatar as FileSystem.documentDirectory + 'avatar', don’t add the / after avatar—this instructs the system to treat the to argument as directory. I would also advise you to suffix the filename with extension.

When it comes to size returned for a directory by getInfoAsync() I don’t think it returns a size of the whole directory, but rather size of a directory entry. For more information check out answers under filesystem - Why does every directory have a size 4096 bytes (4 K)? - Ask Ubuntu.

I’d be happy to help you if you have any more questions. :slight_smile:

Thanks for the thorough explanation
Turns out I was getting readAsStringAsync and readDirectoryAsync mixed up as 1 function! lol
I was under the impression that readAsStringAsync would return an array of file data in the form of string instead of just 1 data, definitely did not read the docs properly…

after changing the setup abit and using writeAsStringAsync instead of moveAsync for the ImagePicker jpeg it all worked out for me as I mentioned in my other post (I separated that post because this one got too lengthy and messy and I’m not authorized to delete it)

Sorry to have wasted ur time, but the explanation was much needed too for the file size, so that helped clear things up for me

Thanks again for the answer, amazing work Expo Team! :smiley:

1 Like

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