Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React-Native call function inside .then async function

I am trying to call a function after the user has taken a picture. I try to do so in the following way:

export default class LA extends Component {
    constructor(props) {
      super(props);
      this.doSomething = this.doSomething.bind(this);
    }


    takePicture() {
      this.camera.capture()
      .then(function(data) {
        doSomething(data.path); //THIS CAUSES THE RUNTIME ERROR
      })
     .catch(err => console.error("error: " + err));
    }

    doSomething(imgPath) {
      console.log(imgPath);
    }


}

And I get the following error when taking a picture:

error: Reference Error: doSomething is not defined

However, If I replace takePicture() with:

takePicture() {
  this.camera.capture()
  .then(function(data) {
    console.log(data.path);
  })
 .catch(err => console.error("error: " + err));
}

The image path is logged, and no error occurs.

like image 580
user7639007 Avatar asked Mar 01 '17 04:03

user7639007


People also ask

How do you call async function inside useEffect?

useEffect(async () => { const users = await fetchUsers(); setUsers(users); return () => { // this never gets called, hello memory leaks... }; }, []); This WORKS, but you should avoid it. Why? Because React's useEffect hook expects a cleanup function returned from it which is called when the component unmounts.

Can we use async with useEffect?

To do this, the function passed to useEffect may return a clean-up function. For example, to create a subscription. 📌 Using an async function makes the callback function return a Promise instead of a cleanup function. And that's why the compiler is yielding in Typescript.

How do you call async function in JSX?

You can't call async function in JSX, it will return a promise. You have to resolve the promise first.

How do you create async function in react native?

const readData = async () => { try { const value = await AsyncStorage. getItem(STORAGE_KEY); if (value !== null) { setInput(value); } } catch (e) { alert('Failed to fetch the input from storage'); } }; To retrieve the data whenever the app starts, invoke this method inside the useEffect hook.


1 Answers

You need to use this in order to call a member function. Here's a working example:

export default class LA extends Component {
  constructor(props) {
    super(props);
    this.doSomething = this.doSomething.bind(this);
  }


  takePicture() {
    this.camera.capture()
    .then((data) => {
      this.doSomething(data.path);
    })
   .catch(err => console.error("error: " + err));
  }

  doSomething(imgPath) {
    console.log(imgPath);
  }


}

Note that I've used an arrow function to reference the correct this inside the callback.

Or you can also pass the function directly, like this.

  takePicture() {
    this.camera.capture()
      .then(this.doSomething)
      .catch(err => console.error("error: " + err));
  }

However, the last approach will not run doSomething on the correct scope, for that you will need to bind doSomething to the class, using an arrow function or in the constructor using bind. A third option is to use a decorator to autobind the method using Babel.

Good luck!

like image 59
Crysfel Avatar answered Nov 10 '22 23:11

Crysfel