4

I am using the fetch API to send a base64 photo to my backend for manipulation, and then I return it. I want to read the photo and write it to my cameraRoll, which I can do. The end goal is to share the photo to instagram, but for some reason the fileReader stops the props from updating. Here is the method:

uploadImageAsync = async (uri, setImageText) => {
    let apiUrl = "some url"

    let uriParts = uri.split('.');
    let fileType = uri[uri.length - 1];

    let formData = new FormData();
    formData.append('photo', {
        uri,
        name: `photo`,
        type: `image/${fileType}`,
    });
    let options = {
        method: 'POST',
        body: formData,
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'multipart/form-data',
        },
    };
    return fetch(apiUrl, options)
        .then(response => {
            return response.blob();
        })
        .then( async myBlob => {
            const fileReader = new FileReader();
            fileReader.readAsText(myBlob);
            const objectURL = URL.createObjectURL(myBlob);
            fileReader.addEventListener('loadend', async (e) => {
                const text = e.srcElement.result;
                this.props.setImageText(text);
                let source = { uri: 'data:image/jpeg;base64,' + text };
                const cameraRollAddress = await CameraRoll.saveToCameraRoll(source.uri, 'photo');
                let instagramURL = `instagram://library?AssetPath=${cameraRollAddress}`;
                Linking.openURL(instagramURL);
                return;
            });
        });
}

The photo saves to the camera roll, but the props are not updated, so the Linking doesn't happen until I press another button somewhere on the screen.

For instance, if I navigate to another screen, Instagram will open with the photo ready to be shared. It doesn't matter what props I try to update, even something as simple as changing the text on the screen: when I use the fileReader, the props won't update. When I take that line out, the props will update, but I need it to get the base64 text string for the image.

Also, the base64 text string does save to the state (I'm actually using Redux), but nothing is updated.

whs.bsmith
  • 386
  • 1
  • 2
  • 12
  • I am not sure if you have solved this yet but what are your props and where are you referencing them? Also when you say "When I take that line out, the props will update", which fileReader line are you talking about? – ShaneG Dec 07 '17 at 11:46
  • ShaneG: I haven't solved this yet. The props involved are in this line `this.props.setImageText(text)`; however, those props aren't doing anything in this function, besides saving the base64 string to the state store in redux. I could actually take that line out and it doesn't affect anything currently. Also, the line that I was referring to was the `fileReader.addEventListener` method. It's needed to read the blob, but it jams React somehow. I can see that the state updates with `this.props.setImageText(text);`, but it won't re-render, or respond to the `Linking`. – whs.bsmith Dec 07 '17 at 14:40
  • Is your uri part of your redux props? – ShaneG Dec 07 '17 at 17:04

1 Answers1

2

Not sure if uri is in your state but a similar question was asked before:

My Redux state has changed, why doesn't React trigger a re-render?

You should never mutate any part of your state in Redux. Up at the very top of your file you are doing the following:

let uriParts = uri.split('.');

This is mutating your state which will prevent it from updating when you use uri below in "addEventListener".

As said in the link, try returning a new uri instead of changing the current one and mutating your state.

Let me know if this helps!

ShaneG
  • 1,498
  • 7
  • 16